Skip to main content

bevy_gizmos_render/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![doc(
3    html_logo_url = "https://bevy.org/assets/icon.png",
4    html_favicon_url = "https://bevy.org/assets/icon.png"
5)]
6
7//! This crate renders `bevy_gizmos` with `bevy_render`.
8
9/// System set label for the systems handling the rendering of gizmos.
10#[derive(const _: () =
    {
        extern crate alloc;
        impl bevy_ecs::schedule::SystemSet for GizmoRenderSystems where
            Self: 'static + ::core::marker::Send + ::core::marker::Sync +
            ::core::clone::Clone + ::core::cmp::Eq + ::core::fmt::Debug +
            ::core::hash::Hash {
            fn dyn_clone(&self)
                -> alloc::boxed::Box<dyn bevy_ecs::schedule::SystemSet> {
                alloc::boxed::Box::new(::core::clone::Clone::clone(self))
            }
        }
    };SystemSet, #[automatically_derived]impl ::core::clone::Clone for GizmoRenderSystems {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::QueueLineGizmos2d => GizmoRenderSystems::QueueLineGizmos2d,
            Self::QueueLineGizmos3d => GizmoRenderSystems::QueueLineGizmos3d,
        }
    }
}Clone, #[automatically_derived]impl ::core::fmt::Debug for GizmoRenderSystems {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                GizmoRenderSystems::QueueLineGizmos2d => "QueueLineGizmos2d",
                GizmoRenderSystems::QueueLineGizmos3d => "QueueLineGizmos3d",
            })
    }
}Debug, #[automatically_derived]impl ::core::hash::Hash for GizmoRenderSystems {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
            state)
    }
}Hash, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
    GizmoRenderSystems {
}
#[automatically_derived]impl ::core::cmp::PartialEq for GizmoRenderSystems {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
            ::core::intrinsics::discriminant_value(other)
    }
}PartialEq, #[automatically_derived]impl ::core::cmp::Eq for GizmoRenderSystems { }Eq)]
11pub enum GizmoRenderSystems {
12    /// Adds gizmos to the [`Transparent2d`](bevy_core_pipeline::core_2d::Transparent2d) render phase
13    #[cfg(feature = "bevy_sprite_render")]
14    QueueLineGizmos2d,
15    /// Adds gizmos to the [`Transparent3d`](bevy_core_pipeline::core_3d::Transparent3d) render phase
16    #[cfg(feature = "bevy_pbr")]
17    QueueLineGizmos3d,
18}
19
20pub mod retained;
21#[cfg(feature = "bevy_pbr")]
22pub mod transform_gizmo_render;
23
24#[cfg(feature = "bevy_sprite_render")]
25mod pipeline_2d;
26#[cfg(feature = "bevy_pbr")]
27mod pipeline_3d;
28
29use bevy_app::{App, Plugin};
30use bevy_ecs::{
31    name::Name,
32    resource::Resource,
33    schedule::{IntoScheduleConfigs, SystemSet},
34    system::Res,
35    world::{FromWorld, World},
36};
37use bevy_math::Affine3Ext;
38use bevy_reflect::Reflect;
39
40use {bevy_gizmos::config::GizmoMeshConfig, bevy_mesh::VertexBufferLayout};
41
42use {
43    crate::retained::extract_linegizmos,
44    bevy_asset::AssetId,
45    bevy_ecs::{
46        component::Component,
47        entity::Entity,
48        prelude::ReflectResource,
49        query::ROQueryItem,
50        system::{
51            lifetimeless::{Read, SRes},
52            Commands, SystemParamItem,
53        },
54    },
55    bevy_math::{Affine3, Affine3A, Vec4},
56    bevy_render::{
57        extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
58        render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
59        render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass},
60        render_resource::{
61            binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayoutEntries,
62            Buffer, BufferInitDescriptor, BufferUsages, ShaderStages, ShaderType, VertexFormat,
63        },
64        renderer::RenderDevice,
65        sync_world::{MainEntity, TemporaryRenderEntity},
66        Extract, ExtractSchedule, Render, RenderApp, RenderStartup, RenderSystems,
67    },
68    bytemuck::cast_slice,
69};
70
71use bevy_render::{
72    extract_resource::{ExtractResource, ExtractResourcePlugin},
73    render_resource::{BindGroupLayoutDescriptor, PipelineCache, VertexAttribute, VertexStepMode},
74};
75
76use bevy_gizmos::{
77    config::{GizmoConfigStore, GizmoLineJoint},
78    GizmoAsset, GizmoHandles,
79};
80
81/// A [`Plugin`] that provides an immediate mode drawing api for visual debugging.
82///
83/// Requires to be loaded after [`PbrPlugin`](bevy_pbr::PbrPlugin) or [`SpriteRenderPlugin`](bevy_sprite_render::SpriteRenderPlugin).
84#[derive(#[automatically_derived]impl ::core::default::Default for GizmoRenderPlugin {
    #[inline]
    fn default() -> Self { GizmoRenderPlugin {} }
}Default)]
85pub struct GizmoRenderPlugin;
86
87impl Plugin for GizmoRenderPlugin {
88    fn build(&self, app: &mut App) {
89        {
90            use bevy_asset::embedded_asset;
91            {
    {
        let mut embedded =
            app.world_mut().resource_mut::<::bevy_asset::io::embedded::EmbeddedAssetRegistry>();
        let path =
            {
                let crate_name =
                    "bevy_gizmos_render".split(':').next().unwrap();
                ::bevy_asset::io::embedded::_embedded_asset_path(crate_name,
                    "src".as_ref(), "src/lib.rs".as_ref(),
                    "lines.wesl".as_ref())
            };
        let watched_path =
            ::bevy_asset::io::embedded::watched_path("src/lib.rs",
                "lines.wesl");
        embedded.insert_asset(watched_path, &path,
            b"// TODO use common view binding\nimport bevy_render::view::View;\nimport bevy_render::maths::affine3_to_square;\n\n@group(0) @binding(0) var<uniform> view: View;\n\nstruct LineGizmoUniform {\n    world_from_local: mat3x4<f32>,\n    line_width: f32,\n    depth_bias: f32,\n    _joints_resolution: u32,\n    gap_scale: f32,\n    line_scale: f32,\n    animation_offset: f32,\n    @if(SIXTEEN_BYTE_ALIGNMENT)\n    // WebGL2 structs must be 16 byte aligned.\n    _padding: vec2<f32>,\n}\n\n@group(1) @binding(0) var<uniform> line_gizmo: LineGizmoUniform;\n\nstruct VertexInput {\n    @location(0) position_a: vec3<f32>,\n    @location(1) position_b: vec3<f32>,\n    @location(2) color_a: vec4<f32>,\n    @location(3) color_b: vec4<f32>,\n    @builtin(vertex_index) index: u32,\n};\n\nstruct VertexOutput {\n    @builtin(position) clip_position: vec4<f32>,\n    @location(0) color: vec4<f32>,\n    @location(1) uv: f32,\n    @location(2) line_fraction: f32,\n};\n\nconst EPSILON: f32 = 4.88e-04;\n\n@vertex\nfn vertex(vertex: VertexInput) -> VertexOutput {\n    var positions = array<vec2<f32>, 6>(\n        vec2(-0.5, 0.),\n        vec2(-0.5, 1.),\n        vec2(0.5, 1.),\n        vec2(-0.5, 0.),\n        vec2(0.5, 1.),\n        vec2(0.5, 0.)\n    );\n    let position = positions[vertex.index];\n\n    let world_from_local = affine3_to_square(line_gizmo.world_from_local);\n\n    // algorithm based on https://wwwtyro.net/2019/11/18/instanced-lines.html\n    var clip_a = view.clip_from_world * world_from_local * vec4(vertex.position_a, 1.);\n    var clip_b = view.clip_from_world * world_from_local * vec4(vertex.position_b, 1.);\n\n    // Manual near plane clipping to avoid errors when doing the perspective divide inside this shader.\n    clip_a = clip_near_plane(clip_a, clip_b);\n    clip_b = clip_near_plane(clip_b, clip_a);\n    let clip = mix(clip_a, clip_b, position.y);\n\n    let resolution = view.viewport.zw;\n    let screen_a = resolution * (0.5 * clip_a.xy / clip_a.w + 0.5);\n    let screen_b = resolution * (0.5 * clip_b.xy / clip_b.w + 0.5);\n\n    let y_basis = normalize(screen_b - screen_a);\n    let x_basis = vec2(-y_basis.y, y_basis.x);\n\n    var color = mix(vertex.color_a, vertex.color_b, position.y);\n\n    var line_width = line_gizmo.line_width;\n    var alpha = 1.;\n\n    var uv: f32;\n@if(PERSPECTIVE) {\n    line_width /= clip.w;\n\n    // get height of near clipping plane in world space\n    let pos0 = view.view_from_clip * vec4(0, -1, 0, 1); // Bottom of the screen\n    let pos1 = view.view_from_clip * vec4(0, 1, 0, 1); // Top of the screen\n    let near_clipping_plane_height = length(pos0.xyz - pos1.xyz);\n\n    // We can\'t use vertex.position_X because we may have changed the clip positions with clip_near_plane\n    let position_a = view.world_from_clip * clip_a;\n    let position_b = view.world_from_clip * clip_b;\n    let world_distance = length(position_a.xyz - position_b.xyz);\n\n    // Offset to compensate for moved clip positions. If removed dots on lines will slide when position a is ofscreen.\n    let clipped_offset = length(position_a.xyz - vertex.position_a);\n\n    uv = (clipped_offset + position.y * world_distance) * resolution.y / near_clipping_plane_height / line_gizmo.line_width;\n} @else {\n    // Get the distance of b to the camera along camera axes\n    let camera_b = view.view_from_clip * clip_b;\n\n    // This differentiates between orthographic and perspective cameras.\n    // For orthographic cameras no depth adaptment (depth_adaptment = 1) is needed.\n    var depth_adaptment: f32;\n    if (clip_b.w == 1.0) {\n        depth_adaptment = 1.0;\n    }\n    else {\n        depth_adaptment = -camera_b.z;\n    }\n    uv = position.y * depth_adaptment * length(screen_b - screen_a) / line_gizmo.line_width;\n}\n\n    // Line thinness fade from https://acegikmo.com/shapes/docs/#anti-aliasing\n    if line_width > 0.0 && line_width < 1. {\n        color.a *= line_width;\n        line_width = 1.;\n    }\n\n    let x_offset = line_width * position.x * x_basis;\n    let screen = mix(screen_a, screen_b, position.y) + x_offset;\n\n    var depth: f32;\n    if line_gizmo.depth_bias >= 0. {\n        depth = clip.z * (1. - line_gizmo.depth_bias);\n    } else {\n        // depth * (clip.w / depth)^-depth_bias. So that when -depth_bias is 1.0, this is equal to clip.w\n        // and when equal to 0.0, it is exactly equal to depth.\n        // the epsilon is here to prevent the depth from exceeding clip.w when -depth_bias = 1.0\n        // clip.w represents the near plane in homogeneous clip space in bevy, having a depth\n        // of this value means nothing can be in front of this\n        // The reason this uses an exponential function is that it makes it much easier for the\n        // user to chose a value that is convenient for them\n        depth = clip.z * exp2(-line_gizmo.depth_bias * log2(clip.w / clip.z - EPSILON));\n    }\n\n    var clip_position = vec4(clip.w * ((2. * screen) / resolution - 1.), depth, clip.w);\n\n    let line_fraction = 2.0 * line_gizmo.line_scale / (line_gizmo.gap_scale + line_gizmo.line_scale);\n    uv /= (line_gizmo.gap_scale + line_gizmo.line_scale) / 2.0;\n    return VertexOutput(clip_position, color, uv, line_fraction);\n}\n\nfn clip_near_plane(a: vec4<f32>, b: vec4<f32>) -> vec4<f32> {\n    // Move a if a is behind the near plane and b is in front.\n    if a.z > a.w && b.z <= b.w {\n        // Interpolate a towards b until it\'s at the near plane.\n        let distance_a = a.z - a.w;\n        let distance_b = b.z - b.w;\n        // Add an epsilon to the interpolator to ensure that the point is\n        // not just behind the clip plane due to floating-point imprecision,\n        // which can lead to lines showing up where they should not.\n        let t = distance_a / (distance_a - distance_b) + EPSILON;\n        return mix(a, b, t);\n    }\n    return a;\n}\n\nstruct FragmentInput {\n    @builtin(position) position: vec4<f32>,\n    @location(0) color: vec4<f32>,\n    @location(1) uv: f32,\n    @location(2) line_fraction: f32,\n};\n\nstruct FragmentOutput {\n    @location(0) color: vec4<f32>,\n};\n\nfn non_solid_uv(in: FragmentInput) -> f32 {\n    @if(PERSPECTIVE)\n    let uv = in.uv;\n    @else\n    let uv = in.uv * in.position.w;\n\n    // subtract the animation offset here since otherwise the animation is\n    // running \"backwards\", e.g.\n    // - from the line end to the line start\n    // - from the arrow tip to the arrow start\n    let animated = uv - line_gizmo.animation_offset;\n\n    const PERIOD: f32 = 2.0;\n    return animated - floor(animated / PERIOD) * PERIOD;\n}\n\n@fragment\nfn fragment_solid(in: FragmentInput) -> FragmentOutput {\n    return FragmentOutput(in.color);\n}\n\n@fragment\nfn fragment_dotted(in: FragmentInput) -> FragmentOutput {\n    let uv = non_solid_uv(in);\n    let alpha = 1.0 - floor(uv);\n\n    return FragmentOutput(vec4(in.color.xyz, in.color.w * alpha));\n}\n\n@fragment\nfn fragment_dashed(in: FragmentInput) -> FragmentOutput {\n    let uv = non_solid_uv(in);\n    let alpha = 1.0 - floor(min(uv / in.line_fraction, 1.0));\n\n    return FragmentOutput(vec4(in.color.xyz, in.color.w * alpha));\n}\n");
    }
};embedded_asset!(app, "lines.wesl");
92            {
    {
        let mut embedded =
            app.world_mut().resource_mut::<::bevy_asset::io::embedded::EmbeddedAssetRegistry>();
        let path =
            {
                let crate_name =
                    "bevy_gizmos_render".split(':').next().unwrap();
                ::bevy_asset::io::embedded::_embedded_asset_path(crate_name,
                    "src".as_ref(), "src/lib.rs".as_ref(),
                    "line_joints.wesl".as_ref())
            };
        let watched_path =
            ::bevy_asset::io::embedded::watched_path("src/lib.rs",
                "line_joints.wesl");
        embedded.insert_asset(watched_path, &path,
            b"import bevy_render::{view::View, maths::affine3_to_square};\n\n@group(0) @binding(0) var<uniform> view: View;\n\n\nstruct LineGizmoUniform {\n    world_from_local: mat3x4<f32>,\n    line_width: f32,\n    depth_bias: f32,\n    resolution: u32,\n    @if(SIXTEEN_BYTE_ALIGNMENT)\n    // WebGL2 structs must be 16 byte aligned.\n    _padding: f32,\n}\n\n@group(1) @binding(0) var<uniform> joints_gizmo: LineGizmoUniform;\n\nstruct VertexInput {\n    @location(0) position_a: vec3<f32>,\n    @location(1) position_b: vec3<f32>,\n    @location(2) position_c: vec3<f32>,\n    @location(3) color: vec4<f32>,\n    @builtin(vertex_index) index: u32,\n};\n\nstruct VertexOutput {\n    @builtin(position) clip_position: vec4<f32>,\n    @location(0) color: vec4<f32>,\n};\n\nconst EPSILON: f32 = 4.88e-04;\n\n@vertex\nfn vertex_bevel(vertex: VertexInput) -> VertexOutput {\n    var positions = array<vec2<f32>, 3>(\n        vec2(0, 0),\n        vec2(0, 0.5),\n        vec2(0.5, 0),\n    );\n    var position = positions[vertex.index];\n\n    let world_from_local = affine3_to_square(joints_gizmo.world_from_local);\n\n    var clip_a = view.clip_from_world * world_from_local * vec4(vertex.position_a, 1.);\n    var clip_b = view.clip_from_world * world_from_local * vec4(vertex.position_b, 1.);\n    var clip_c = view.clip_from_world * world_from_local * vec4(vertex.position_c, 1.);\n\n    // Manual near plane clipping to avoid errors when doing the perspective divide inside this shader.\n    clip_a = clip_near_plane(clip_a, clip_c);\n    clip_b = clip_near_plane(clip_b, clip_a);\n    clip_c = clip_near_plane(clip_c, clip_b);\n    clip_a = clip_near_plane(clip_a, clip_c);\n\n    let resolution = view.viewport.zw;\n    let screen_a = resolution * (0.5 * clip_a.xy / clip_a.w + 0.5);\n    let screen_b = resolution * (0.5 * clip_b.xy / clip_b.w + 0.5);\n    let screen_c = resolution * (0.5 * clip_c.xy / clip_c.w + 0.5);\n\n    var color = vertex.color;\n    var line_width = joints_gizmo.line_width;\n\n    @if(PERSPECTIVE)\n    line_width /= clip_b.w;\n\n    // Line thinness fade from https://acegikmo.com/shapes/docs/#anti-aliasing\n    if line_width > 0.0 && line_width < 1. {\n        color.a *= line_width;\n        line_width = 1.;\n    }\n\n    let ab = normalize(screen_b - screen_a);\n    let cb = normalize(screen_b - screen_c);\n    let ab_norm = vec2(-ab.y, ab.x);\n    let cb_norm = vec2(cb.y, -cb.x);\n    let tangent = normalize(ab - cb);\n    let normal = vec2(-tangent.y, tangent.x);\n    let sigma = sign(dot(ab + cb, normal));\n\n    var p0 = line_width * sigma * ab_norm;\n    var p1 = line_width * sigma * cb_norm;\n\n    let screen = screen_b + position.x * p0 + position.y * p1;\n\n    let depth = depth(clip_b);\n\n    var clip_position = vec4(clip_b.w * ((2. * screen) / resolution - 1.), depth, clip_b.w);\n    return VertexOutput(clip_position, color);\n}\n\n@vertex\nfn vertex_miter(vertex: VertexInput) -> VertexOutput {\n    var positions = array<vec3<f32>, 6>(\n        vec3(0, 0, 0),\n        vec3(0.5, 0, 0),\n        vec3(0, 0.5, 0),\n        vec3(0, 0, 0),\n        vec3(0, 0.5, 0),\n        vec3(0, 0, 0.5),\n    );\n    var position = positions[vertex.index];\n\n    let world_from_local = affine3_to_square(joints_gizmo.world_from_local);\n\n    var clip_a = view.clip_from_world * world_from_local * vec4(vertex.position_a, 1.);\n    var clip_b = view.clip_from_world * world_from_local * vec4(vertex.position_b, 1.);\n    var clip_c = view.clip_from_world * world_from_local * vec4(vertex.position_c, 1.);\n\n    // Manual near plane clipping to avoid errors when doing the perspective divide inside this shader.\n    clip_a = clip_near_plane(clip_a, clip_c);\n    clip_b = clip_near_plane(clip_b, clip_a);\n    clip_c = clip_near_plane(clip_c, clip_b);\n    clip_a = clip_near_plane(clip_a, clip_c);\n\n    let resolution = view.viewport.zw;\n    let screen_a = resolution * (0.5 * clip_a.xy / clip_a.w + 0.5);\n    let screen_b = resolution * (0.5 * clip_b.xy / clip_b.w + 0.5);\n    let screen_c = resolution * (0.5 * clip_c.xy / clip_c.w + 0.5);\n\n    var color = vertex.color;\n    var line_width = joints_gizmo.line_width;\n\n    @if(PERSPECTIVE)\n    line_width /= clip_b.w;\n\n    // Line thinness fade from https://acegikmo.com/shapes/docs/#anti-aliasing\n    if line_width > 0.0 && line_width < 1. {\n        color.a *= line_width;\n        line_width = 1.;\n    }\n\n    let ab = normalize(screen_b - screen_a);\n    let cb = normalize(screen_b - screen_c);\n    let ab_norm = vec2(-ab.y, ab.x);\n    let cb_norm = vec2(cb.y, -cb.x);\n    let tangent = normalize(ab - cb);\n    let normal = vec2(-tangent.y, tangent.x);\n    let sigma = sign(dot(ab + cb, normal));\n\n    var p0 = line_width * sigma * ab_norm;\n    var p1 = line_width * sigma * normal / dot(normal, ab_norm);\n    var p2 = line_width * sigma * cb_norm;\n    \n    var screen = screen_b + position.x * p0 + position.y * p1 + position.z * p2;\n\n    var depth = depth(clip_b);\n\n    var clip_position = vec4(clip_b.w * ((2. * screen) / resolution - 1.), depth, clip_b.w);\n    return VertexOutput(clip_position, color);\n}\n\n@vertex\nfn vertex_round(vertex: VertexInput) -> VertexOutput {\n    let world_from_local = affine3_to_square(joints_gizmo.world_from_local);\n\n    var clip_a = view.clip_from_world * world_from_local * vec4(vertex.position_a, 1.);\n    var clip_b = view.clip_from_world * world_from_local * vec4(vertex.position_b, 1.);\n    var clip_c = view.clip_from_world * world_from_local * vec4(vertex.position_c, 1.);\n\n    // Manual near plane clipping to avoid errors when doing the perspective divide inside this shader.\n    clip_a = clip_near_plane(clip_a, clip_c);\n    clip_b = clip_near_plane(clip_b, clip_a);\n    clip_c = clip_near_plane(clip_c, clip_b);\n    clip_a = clip_near_plane(clip_a, clip_c);\n\n    let resolution = view.viewport.zw;\n    let screen_a = resolution * (0.5 * clip_a.xy / clip_a.w + 0.5);\n    let screen_b = resolution * (0.5 * clip_b.xy / clip_b.w + 0.5);\n    let screen_c = resolution * (0.5 * clip_c.xy / clip_c.w + 0.5);\n\n    var color = vertex.color;\n    var line_width = joints_gizmo.line_width;\n\n    @if(PERSPECTIVE)\n    line_width /= clip_b.w;\n\n    // Line thinness fade from https://acegikmo.com/shapes/docs/#anti-aliasing\n    if line_width > 0.0 && line_width < 1. {\n        color.a *= line_width;\n        line_width = 1.;\n    }\n\n    let ab = normalize(screen_b - screen_a);\n    let cb = normalize(screen_b - screen_c);\n    let ab_norm = vec2(-ab.y, ab.x);\n    let cb_norm = vec2(cb.y, -cb.x);\n\n    // We render `joints_gizmo.resolution`triangles. The vertices in each triangle are ordered as follows:\n    // - 0: The \'center\' vertex at `screen_b`.\n    // - 1: The vertex closer to the ab line.\n    // - 2: The vertex closer to the cb line. \n    var in_triangle_index = f32(vertex.index) % 3.0;\n    var tri_index = floor(f32(vertex.index) / 3.0);\n    var radius = sign(in_triangle_index) * 0.5 * line_width;\n    var theta = acos(dot(ab_norm, cb_norm));\n    let sigma = sign(dot(ab_norm, cb));\n    var angle = theta * (tri_index + in_triangle_index - 1) / f32(joints_gizmo.resolution);\n    var position_x = sigma * radius * cos(angle);\n    var position_y = radius * sin(angle);\n\n    var screen = screen_b + position_x * ab_norm + position_y * ab;\n\n    var depth = depth(clip_b);\n\n    var clip_position = vec4(clip_b.w * ((2. * screen) / resolution - 1.), depth, clip_b.w);\n    return VertexOutput(clip_position, color);\n}\n\nfn clip_near_plane(a: vec4<f32>, b: vec4<f32>) -> vec4<f32> {\n    // Move a if a is behind the near plane and b is in front. \n    if a.z > a.w && b.z <= b.w {\n        // Interpolate a towards b until it\'s at the near plane.\n        let distance_a = a.z - a.w;\n        let distance_b = b.z - b.w;\n        // Add an epsilon to the interpolator to ensure that the point is\n        // not just behind the clip plane due to floating-point imprecision.\n        let t = distance_a / (distance_a - distance_b) + EPSILON;\n        return mix(a, b, t);\n    }\n    return a;\n}\n\nfn depth(clip: vec4<f32>) -> f32 {\n    var depth: f32;\n    if joints_gizmo.depth_bias >= 0. {\n        depth = clip.z * (1. - joints_gizmo.depth_bias);\n    } else {\n        // depth * (clip.w / depth)^-depth_bias. So that when -depth_bias is 1.0, this is equal to clip.w\n        // and when equal to 0.0, it is exactly equal to depth.\n        // the epsilon is here to prevent the depth from exceeding clip.w when -depth_bias = 1.0\n        // clip.w represents the near plane in homogeneous clip space in bevy, having a depth\n        // of this value means nothing can be in front of this\n        // The reason this uses an exponential function is that it makes it much easier for the\n        // user to chose a value that is convenient for them\n        depth = clip.z * exp2(-joints_gizmo.depth_bias * log2(clip.w / clip.z - EPSILON));\n    }\n    return depth;\n}\n\nstruct FragmentInput {\n    @location(0) color: vec4<f32>,\n};\n\nstruct FragmentOutput {\n    @location(0) color: vec4<f32>,\n};\n\n@fragment\nfn fragment(in: FragmentInput) -> FragmentOutput {\n    // return FragmentOutput(vec4(1, 1, 1, 1));\n    return FragmentOutput(in.color);\n}\n");
    }
};embedded_asset!(app, "line_joints.wesl");
93        }
94
95        app.add_plugins(UniformComponentPlugin::<LineGizmoUniform>::default())
96            .add_plugins(RenderAssetPlugin::<GpuLineGizmo>::default())
97            .add_plugins(ExtractResourcePlugin::<LineGizmoEntities>::default())
98            .init_resource::<LineGizmoEntities>();
99
100        if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
101            render_app.add_systems(RenderStartup, init_line_gizmo_uniform_bind_group_layout);
102
103            render_app.add_systems(
104                Render,
105                prepare_line_gizmo_bind_group.in_set(RenderSystems::PrepareBindGroups),
106            );
107
108            render_app.add_systems(ExtractSchedule, (extract_gizmo_data, extract_linegizmos));
109
110            #[cfg(feature = "bevy_sprite_render")]
111            if app.is_plugin_added::<bevy_sprite_render::SpriteRenderPlugin>() {
112                app.add_plugins(pipeline_2d::LineGizmo2dPlugin);
113            } else {
114                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/lib.rs:114",
                        "bevy_gizmos_render", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/lib.rs"),
                        ::tracing_core::__macro_support::Option::Some(114u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_gizmos_render"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("bevy_sprite_render feature is enabled but bevy_sprite_render::SpriteRenderPlugin was not detected. Are you sure you loaded GizmoPlugin after SpriteRenderPlugin?")
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};tracing::warn!("bevy_sprite_render feature is enabled but bevy_sprite_render::SpriteRenderPlugin was not detected. Are you sure you loaded GizmoPlugin after SpriteRenderPlugin?");
115            }
116            #[cfg(feature = "bevy_pbr")]
117            if app.is_plugin_added::<bevy_pbr::PbrPlugin>() {
118                app.add_plugins(pipeline_3d::LineGizmo3dPlugin);
119                app.add_plugins(transform_gizmo_render::TransformGizmoRenderPlugin);
120            } else {
121                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/lib.rs:121",
                        "bevy_gizmos_render", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/lib.rs"),
                        ::tracing_core::__macro_support::Option::Some(121u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_gizmos_render"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("bevy_pbr feature is enabled but bevy_pbr::PbrPlugin was not detected. Are you sure you loaded GizmoPlugin after PbrPlugin?")
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};tracing::warn!("bevy_pbr feature is enabled but bevy_pbr::PbrPlugin was not detected. Are you sure you loaded GizmoPlugin after PbrPlugin?");
122            }
123        } else {
124            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/lib.rs:124",
                        "bevy_gizmos_render", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/lib.rs"),
                        ::tracing_core::__macro_support::Option::Some(124u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_gizmos_render"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("bevy_render feature is enabled but RenderApp was not detected. Are you sure you loaded GizmoPlugin after RenderPlugin?")
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};tracing::warn!("bevy_render feature is enabled but RenderApp was not detected. Are you sure you loaded GizmoPlugin after RenderPlugin?");
125        }
126    }
127}
128
129fn init_line_gizmo_uniform_bind_group_layout(mut commands: Commands) {
130    let line_layout = BindGroupLayoutDescriptor::new(
131        "LineGizmoUniform layout",
132        &BindGroupLayoutEntries::single(
133            ShaderStages::VERTEX_FRAGMENT,
134            uniform_buffer::<LineGizmoUniform>(true),
135        ),
136    );
137
138    commands.insert_resource(LineGizmoUniformBindgroupLayout {
139        layout: line_layout,
140    });
141}
142
143fn extract_gizmo_data(
144    mut commands: Commands,
145    handles: Extract<Res<GizmoHandles>>,
146    config: Extract<Res<GizmoConfigStore>>,
147) {
148    use bevy_gizmos::config::GizmoLineStyle;
149    use bevy_utils::once;
150    use tracing::warn;
151
152    for (group_type_id, handle) in handles.handles() {
153        let Some((config, _)) = config.get_config_dyn(group_type_id) else {
154            continue;
155        };
156
157        if !config.enabled {
158            continue;
159        }
160
161        #[cfg_attr(
162            not(any(feature = "bevy_pbr", feature = "bevy_sprite_render")),
163            expect(
164                unused_variables,
165                reason = "`handle` is unused when bevy_pbr and bevy_sprite_render are both disabled."
166            )
167        )]
168        let Some(handle) = handle
169        else {
170            continue;
171        };
172
173        let joints_resolution = if let GizmoLineJoint::Round(resolution) = config.line.joints {
174            resolution
175        } else {
176            0
177        };
178
179        let (gap_scale, line_scale) = if let GizmoLineStyle::Dashed {
180            gap_scale,
181            line_scale,
182        } = config.line.style
183        {
184            if gap_scale <= 0.0 {
185                {
    static SHOULD_FIRE: ::bevy_utils::OnceFlag =
        ::bevy_utils::OnceFlag::new();
    if SHOULD_FIRE.set() {
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("event src/lib.rs:185",
                                "bevy_gizmos_render", ::tracing::Level::WARN,
                                ::tracing_core::__macro_support::Option::Some("src/lib.rs"),
                                ::tracing_core::__macro_support::Option::Some(185u32),
                                ::tracing_core::__macro_support::Option::Some("bevy_gizmos_render"),
                                ::tracing_core::field::FieldSet::new(&["message"],
                                    ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::EVENT)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let enabled =
                ::tracing::Level::WARN <=
                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                        ::tracing::Level::WARN <=
                            ::tracing::level_filters::LevelFilter::current() &&
                    {
                        let interest = __CALLSITE.interest();
                        !interest.is_never() &&
                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                interest)
                    };
            if enabled {
                (|value_set: ::tracing::field::ValueSet|
                            {
                                let meta = __CALLSITE.metadata();
                                ::tracing::Event::dispatch(meta, &value_set);
                                ;
                            })({
                        #[allow(unused_imports)]
                        use ::tracing::field::{debug, display, Value};
                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("When using gizmos with the line style `GizmoLineStyle::Dashed{{..}}` the gap scale should be greater than zero.")
                                                    as &dyn ::tracing::field::Value))])
                    });
            } else { ; }
        };
    }
};once!(warn!("When using gizmos with the line style `GizmoLineStyle::Dashed{{..}}` the gap scale should be greater than zero."));
186            }
187            if line_scale <= 0.0 {
188                {
    static SHOULD_FIRE: ::bevy_utils::OnceFlag =
        ::bevy_utils::OnceFlag::new();
    if SHOULD_FIRE.set() {
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("event src/lib.rs:188",
                                "bevy_gizmos_render", ::tracing::Level::WARN,
                                ::tracing_core::__macro_support::Option::Some("src/lib.rs"),
                                ::tracing_core::__macro_support::Option::Some(188u32),
                                ::tracing_core::__macro_support::Option::Some("bevy_gizmos_render"),
                                ::tracing_core::field::FieldSet::new(&["message"],
                                    ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::EVENT)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let enabled =
                ::tracing::Level::WARN <=
                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                        ::tracing::Level::WARN <=
                            ::tracing::level_filters::LevelFilter::current() &&
                    {
                        let interest = __CALLSITE.interest();
                        !interest.is_never() &&
                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                interest)
                    };
            if enabled {
                (|value_set: ::tracing::field::ValueSet|
                            {
                                let meta = __CALLSITE.metadata();
                                ::tracing::Event::dispatch(meta, &value_set);
                                ;
                            })({
                        #[allow(unused_imports)]
                        use ::tracing::field::{debug, display, Value};
                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("When using gizmos with the line style `GizmoLineStyle::Dashed{{..}}` the line scale should be greater than zero.")
                                                    as &dyn ::tracing::field::Value))])
                    });
            } else { ; }
        };
    }
};once!(warn!("When using gizmos with the line style `GizmoLineStyle::Dashed{{..}}` the line scale should be greater than zero."));
189            }
190            (gap_scale, line_scale)
191        } else {
192            (1.0, 1.0)
193        };
194
195        commands.spawn((
196            LineGizmoUniform {
197                world_from_local: Affine3::from(Affine3A::IDENTITY).to_transpose(),
198                line_width: config.line.width,
199                depth_bias: config.depth_bias,
200                joints_resolution,
201                gap_scale,
202                line_scale,
203                animation_offset: config.line.animation_offset,
204                #[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
205                _webgl2_padding: Default::default(),
206            },
207            #[cfg(any(feature = "bevy_pbr", feature = "bevy_sprite_render"))]
208            GizmoMeshConfig {
209                line_perspective: config.line.perspective,
210                line_style: config.line.style,
211                line_joints: config.line.joints,
212                render_layers: config.render_layers.clone(),
213                handle: handle.clone(),
214            },
215            // The immediate mode API does not have a main world entity to refer to,
216            // but we do need MainEntity on this render entity for the systems to find it.
217            MainEntity::from(Entity::PLACEHOLDER),
218            TemporaryRenderEntity::default(),
219        ));
220    }
221}
222
223#[derive(impl bevy_ecs::component::Component for LineGizmoUniform where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::Table;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {}
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, impl bevy_render::render_resource::encase::private::ShaderType for
    LineGizmoUniform where
    [Vec4; 3]: bevy_render::render_resource::encase::private::ShaderType +
    bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderType +
    bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderType +
    bevy_render::render_resource::encase::private::ShaderSize,
    u32: bevy_render::render_resource::encase::private::ShaderType +
    bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderType +
    bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderType +
    bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderType {
    type ExtraMetadata =
        bevy_render::render_resource::encase::private::StructMetadata<7usize>;
    const METADATA:
        bevy_render::render_resource::encase::private::Metadata<Self::ExtraMetadata>
        =
        {
            let struct_alignment =
                bevy_render::render_resource::encase::private::AlignmentValue::max([<[Vec4; 3]
                                    as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment(),
                            <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment(),
                            <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment(),
                            <u32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment(),
                            <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment(),
                            <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment(),
                            <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment()]);
            let extra =
                {
                    let mut paddings = [0; 7usize];
                    let mut offsets = [0; 7usize];
                    let mut offset = 0;
                    offset +=
                        <[Vec4; 3] as
                                bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                    offsets[1usize] =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().round_up(offset);
                    let padding =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().padding_needed_for(offset);
                    offset += padding;
                    paddings[0usize] = padding;
                    offset +=
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                    offsets[2usize] =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().round_up(offset);
                    let padding =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().padding_needed_for(offset);
                    offset += padding;
                    paddings[1usize] = padding;
                    offset +=
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                    offsets[3usize] =
                        <u32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().round_up(offset);
                    let padding =
                        <u32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().padding_needed_for(offset);
                    offset += padding;
                    paddings[2usize] = padding;
                    offset +=
                        <u32 as
                                bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                    offsets[4usize] =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().round_up(offset);
                    let padding =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().padding_needed_for(offset);
                    offset += padding;
                    paddings[3usize] = padding;
                    offset +=
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                    offsets[5usize] =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().round_up(offset);
                    let padding =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().padding_needed_for(offset);
                    offset += padding;
                    paddings[4usize] = padding;
                    offset +=
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                    offsets[6usize] =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().round_up(offset);
                    let padding =
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.alignment().padding_needed_for(offset);
                    offset += padding;
                    paddings[5usize] = padding;
                    offset +=
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                    paddings[6usize] =
                        struct_alignment.padding_needed_for(offset);
                    bevy_render::render_resource::encase::private::StructMetadata {
                        offsets,
                        paddings,
                    }
                };
            let min_size =
                {
                    let mut offset = extra.offsets[7usize - 1];
                    offset +=
                        <f32 as
                                    bevy_render::render_resource::encase::private::ShaderType>::METADATA.min_size().get();
                    bevy_render::render_resource::encase::private::SizeValue::new(struct_alignment.round_up(offset))
                };
            bevy_render::render_resource::encase::private::Metadata {
                alignment: struct_alignment,
                has_uniform_min_alignment: true,
                min_size,
                is_pod: false,
                extra,
            }
        };
    const UNIFORM_COMPAT_ASSERT: fn() =
        ||
            bevy_render::render_resource::encase::private::consume_zsts([<[Vec4; 3]
                                as
                                bevy_render::render_resource::encase::private::ShaderType>::UNIFORM_COMPAT_ASSERT(),
                        if let ::core::option::Option::Some(min_alignment) =
                                <[Vec4; 3] as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(0usize);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = min_alignment.is_aligned(offset) {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset of field '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"world_from_local" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be a multiple of "
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (current offset: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &offset {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        }, (),
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderType>::UNIFORM_COMPAT_ASSERT(),
                        if let ::core::option::Option::Some(min_alignment) =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(1usize);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = min_alignment.is_aligned(offset) {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset of field '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"line_width" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be a multiple of "
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (current offset: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &offset {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        if let ::core::option::Option::Some(min_alignment) =
                                <[Vec4; 3] as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let prev_offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(1usize
                                        - 1);
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(1usize);
                            let diff = offset - prev_offset;
                            let prev_size =
                                <[Vec4; 3] as
                                        bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                            let prev_size = min_alignment.round_up(prev_size);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = diff >= prev_size {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset between fields '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"world_from_local" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' and '" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"line_width" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be at least " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (currently: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &diff {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderType>::UNIFORM_COMPAT_ASSERT(),
                        if let ::core::option::Option::Some(min_alignment) =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(2usize);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = min_alignment.is_aligned(offset) {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset of field '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"depth_bias" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be a multiple of "
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (current offset: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &offset {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        if let ::core::option::Option::Some(min_alignment) =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let prev_offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(2usize
                                        - 1);
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(2usize);
                            let diff = offset - prev_offset;
                            let prev_size =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                            let prev_size = min_alignment.round_up(prev_size);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = diff >= prev_size {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset between fields '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"line_width" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' and '" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"depth_bias" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be at least " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (currently: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &diff {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        <u32 as
                                bevy_render::render_resource::encase::private::ShaderType>::UNIFORM_COMPAT_ASSERT(),
                        if let ::core::option::Option::Some(min_alignment) =
                                <u32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(3usize);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = min_alignment.is_aligned(offset) {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset of field '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"joints_resolution" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be a multiple of "
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (current offset: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &offset {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        if let ::core::option::Option::Some(min_alignment) =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let prev_offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(3usize
                                        - 1);
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(3usize);
                            let diff = offset - prev_offset;
                            let prev_size =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                            let prev_size = min_alignment.round_up(prev_size);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = diff >= prev_size {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset between fields '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"depth_bias" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' and '" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"joints_resolution" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be at least " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (currently: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &diff {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderType>::UNIFORM_COMPAT_ASSERT(),
                        if let ::core::option::Option::Some(min_alignment) =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(4usize);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = min_alignment.is_aligned(offset) {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset of field '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"gap_scale" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be a multiple of "
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (current offset: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &offset {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        if let ::core::option::Option::Some(min_alignment) =
                                <u32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let prev_offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(4usize
                                        - 1);
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(4usize);
                            let diff = offset - prev_offset;
                            let prev_size =
                                <u32 as
                                        bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                            let prev_size = min_alignment.round_up(prev_size);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = diff >= prev_size {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset between fields '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"joints_resolution" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' and '" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"gap_scale" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be at least " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (currently: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &diff {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderType>::UNIFORM_COMPAT_ASSERT(),
                        if let ::core::option::Option::Some(min_alignment) =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(5usize);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = min_alignment.is_aligned(offset) {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset of field '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"line_scale" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be a multiple of "
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (current offset: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &offset {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        if let ::core::option::Option::Some(min_alignment) =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let prev_offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(5usize
                                        - 1);
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(5usize);
                            let diff = offset - prev_offset;
                            let prev_size =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                            let prev_size = min_alignment.round_up(prev_size);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = diff >= prev_size {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset between fields '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"gap_scale" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' and '" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"line_scale" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be at least " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (currently: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &diff {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        <f32 as
                                bevy_render::render_resource::encase::private::ShaderType>::UNIFORM_COMPAT_ASSERT(),
                        if let ::core::option::Option::Some(min_alignment) =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(6usize);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = min_alignment.is_aligned(offset) {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset of field '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"animation_offset" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be a multiple of "
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (current offset: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &offset {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        },
                        if let ::core::option::Option::Some(min_alignment) =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.uniform_min_alignment()
                            {
                            let prev_offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(6usize
                                        - 1);
                            let offset =
                                <Self as
                                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.offset(6usize);
                            let diff = offset - prev_offset;
                            let prev_size =
                                <f32 as
                                        bevy_render::render_resource::encase::private::ShaderSize>::SHADER_SIZE.get();
                            let prev_size = min_alignment.round_up(prev_size);
                            {

                                #[allow(clippy :: equatable_if_let)]
                                if let false = diff >= prev_size {
                                    {
                                        let mut fmt: ::const_panic::FmtArg =
                                            ::const_panic::FmtArg::DEBUG;
                                        match &[::const_panic::StdWrapper(&match &"offset between fields '"
                                                                            {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"line_scale" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' and '" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"animation_offset" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &"' must be at least " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &min_alignment.get() {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &" (currently: " {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &diff {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt)).deref_panic_vals(),
                                                        ::const_panic::StdWrapper(&match &")" {
                                                                            reff =>
                                                                                ::const_panic::__::PanicFmt::PROOF.infer(reff).coerce(reff),
                                                                        }.to_panicvals(fmt.set_display().set_alternate(false))).deref_panic_vals()]
                                            {
                                            args => ::const_panic::concat_panic(args),
                                        }
                                    }
                                }
                            }
                        }]);
    fn size(&self) -> ::core::num::NonZeroU64 {
        let mut offset = Self::METADATA.last_offset();
        offset +=
            bevy_render::render_resource::encase::private::ShaderType::size(&self.animation_offset).get();
        bevy_render::render_resource::encase::private::SizeValue::new(Self::METADATA.alignment().round_up(offset)).0
    }
}
impl bevy_render::render_resource::encase::private::WriteInto for
    LineGizmoUniform where
    Self: bevy_render::render_resource::encase::private::ShaderType<ExtraMetadata
    = bevy_render::render_resource::encase::private::StructMetadata<7usize>>,
    for<'__> [Vec4; 3]: bevy_render::render_resource::encase::private::WriteInto,
    for<'__> f32: bevy_render::render_resource::encase::private::WriteInto,
    for<'__> f32: bevy_render::render_resource::encase::private::WriteInto,
    for<'__> u32: bevy_render::render_resource::encase::private::WriteInto,
    for<'__> f32: bevy_render::render_resource::encase::private::WriteInto,
    for<'__> f32: bevy_render::render_resource::encase::private::WriteInto,
    for<'__> f32: bevy_render::render_resource::encase::private::WriteInto {
    #[inline]
    fn write_into<B: bevy_render::render_resource::encase::private::BufferMut>(&self,
        writer:
            &mut bevy_render::render_resource::encase::private::Writer<B>) {
        bevy_render::render_resource::encase::private::WriteInto::write_into(&self.world_from_local,
            writer);
        bevy_render::render_resource::encase::private::Writer::advance(writer,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(0usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::WriteInto::write_into(&self.line_width,
            writer);
        bevy_render::render_resource::encase::private::Writer::advance(writer,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(1usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::WriteInto::write_into(&self.depth_bias,
            writer);
        bevy_render::render_resource::encase::private::Writer::advance(writer,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(2usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::WriteInto::write_into(&self.joints_resolution,
            writer);
        bevy_render::render_resource::encase::private::Writer::advance(writer,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(3usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::WriteInto::write_into(&self.gap_scale,
            writer);
        bevy_render::render_resource::encase::private::Writer::advance(writer,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(4usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::WriteInto::write_into(&self.line_scale,
            writer);
        bevy_render::render_resource::encase::private::Writer::advance(writer,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(5usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::WriteInto::write_into(&self.animation_offset,
            writer);
        bevy_render::render_resource::encase::private::Writer::advance(writer,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(6usize)
                as ::core::primitive::usize);
    }
}
impl bevy_render::render_resource::encase::private::ReadFrom for
    LineGizmoUniform where
    Self: bevy_render::render_resource::encase::private::ShaderType<ExtraMetadata
    = bevy_render::render_resource::encase::private::StructMetadata<7usize>>,
    for<'__> [Vec4; 3]: bevy_render::render_resource::encase::private::ReadFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::ReadFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::ReadFrom,
    for<'__> u32: bevy_render::render_resource::encase::private::ReadFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::ReadFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::ReadFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::ReadFrom {
    #[inline]
    fn read_from<B: bevy_render::render_resource::encase::private::BufferRef>(&mut self,
        reader:
            &mut bevy_render::render_resource::encase::private::Reader<B>) {
        bevy_render::render_resource::encase::private::ReadFrom::read_from(&mut self.world_from_local,
            reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(0usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::ReadFrom::read_from(&mut self.line_width,
            reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(1usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::ReadFrom::read_from(&mut self.depth_bias,
            reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(2usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::ReadFrom::read_from(&mut self.joints_resolution,
            reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(3usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::ReadFrom::read_from(&mut self.gap_scale,
            reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(4usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::ReadFrom::read_from(&mut self.line_scale,
            reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(5usize)
                as ::core::primitive::usize);
        bevy_render::render_resource::encase::private::ReadFrom::read_from(&mut self.animation_offset,
            reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(6usize)
                as ::core::primitive::usize);
    }
}
impl bevy_render::render_resource::encase::private::CreateFrom for
    LineGizmoUniform where
    Self: bevy_render::render_resource::encase::private::ShaderType<ExtraMetadata
    = bevy_render::render_resource::encase::private::StructMetadata<7usize>>,
    for<'__> [Vec4; 3]: bevy_render::render_resource::encase::private::CreateFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::CreateFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::CreateFrom,
    for<'__> u32: bevy_render::render_resource::encase::private::CreateFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::CreateFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::CreateFrom,
    for<'__> f32: bevy_render::render_resource::encase::private::CreateFrom {
    #[inline]
    fn create_from<B: bevy_render::render_resource::encase::private::BufferRef>(reader:
            &mut bevy_render::render_resource::encase::private::Reader<B>)
        -> Self {
        let world_from_local =
            bevy_render::render_resource::encase::private::CreateFrom::create_from(reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(0usize)
                as ::core::primitive::usize);
        let line_width =
            bevy_render::render_resource::encase::private::CreateFrom::create_from(reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(1usize)
                as ::core::primitive::usize);
        let depth_bias =
            bevy_render::render_resource::encase::private::CreateFrom::create_from(reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(2usize)
                as ::core::primitive::usize);
        let joints_resolution =
            bevy_render::render_resource::encase::private::CreateFrom::create_from(reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(3usize)
                as ::core::primitive::usize);
        let gap_scale =
            bevy_render::render_resource::encase::private::CreateFrom::create_from(reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(4usize)
                as ::core::primitive::usize);
        let line_scale =
            bevy_render::render_resource::encase::private::CreateFrom::create_from(reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(5usize)
                as ::core::primitive::usize);
        let animation_offset =
            bevy_render::render_resource::encase::private::CreateFrom::create_from(reader);
        bevy_render::render_resource::encase::private::Reader::advance(reader,
            <Self as
                        bevy_render::render_resource::encase::private::ShaderType>::METADATA.padding(6usize)
                as ::core::primitive::usize);
        {
            let mut uninit_struct =
                ::core::mem::MaybeUninit::<Self>::uninit();
            let ptr =
                ::core::mem::MaybeUninit::as_mut_ptr(&mut uninit_struct);
            let field_ptr = unsafe { &raw mut (*ptr).world_from_local };
            unsafe { field_ptr.write(world_from_local) };
            ;
            let field_ptr = unsafe { &raw mut (*ptr).line_width };
            unsafe { field_ptr.write(line_width) };
            ;
            let field_ptr = unsafe { &raw mut (*ptr).depth_bias };
            unsafe { field_ptr.write(depth_bias) };
            ;
            let field_ptr = unsafe { &raw mut (*ptr).joints_resolution };
            unsafe { field_ptr.write(joints_resolution) };
            ;
            let field_ptr = unsafe { &raw mut (*ptr).gap_scale };
            unsafe { field_ptr.write(gap_scale) };
            ;
            let field_ptr = unsafe { &raw mut (*ptr).line_scale };
            unsafe { field_ptr.write(line_scale) };
            ;
            let field_ptr = unsafe { &raw mut (*ptr).animation_offset };
            unsafe { field_ptr.write(animation_offset) };
            ;
            unsafe { ::core::mem::MaybeUninit::assume_init(uninit_struct) }
        }
    }
}
impl bevy_render::render_resource::encase::private::ShaderSize for
    LineGizmoUniform where
    [Vec4; 3]: bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderSize,
    u32: bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderSize,
    f32: bevy_render::render_resource::encase::private::ShaderSize {}ShaderType, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for LineGizmoUniform {
}
#[automatically_derived]impl ::core::clone::Clone for LineGizmoUniform {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<[Vec4; 3]>;
        let _: ::core::clone::AssertParamIsClone<f32>;
        let _: ::core::clone::AssertParamIsClone<u32>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::marker::Copy for LineGizmoUniform { }Copy)]
224struct LineGizmoUniform {
225    world_from_local: [Vec4; 3],
226    line_width: f32,
227    depth_bias: f32,
228    // Only used by gizmo line t if the current configs `line_joints` is set to `GizmoLineJoint::Round(_)`
229    joints_resolution: u32,
230    // Only used if the current configs `line_style` is set to `GizmoLineStyle::Dashed{_}`
231    gap_scale: f32,
232    line_scale: f32,
233    animation_offset: f32,
234    /// WebGL2 structs must be 16 byte aligned.
235    #[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
236    _webgl2_padding: bevy_math::Vec2,
237}
238
239#[cfg_attr(
240    not(any(feature = "bevy_pbr", feature = "bevy_sprite_render")),
241    expect(
242        dead_code,
243        reason = "fields are unused when bevy_pbr and bevy_sprite_render are both disabled."
244    )
245)]
246#[derive(#[automatically_derived]impl ::core::fmt::Debug for GpuLineGizmo {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["list_position_buffer", "list_color_buffer",
                        "list_vertex_count", "strip_position_buffer",
                        "strip_color_buffer", "strip_vertex_count"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.list_position_buffer, &self.list_color_buffer,
                        &self.list_vertex_count, &self.strip_position_buffer,
                        &self.strip_color_buffer, &&self.strip_vertex_count];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "GpuLineGizmo",
            names, values)
    }
}Debug, #[automatically_derived]impl ::core::clone::Clone for GpuLineGizmo {
    #[inline]
    fn clone(&self) -> Self {
        GpuLineGizmo {
            list_position_buffer: ::core::clone::Clone::clone(&self.list_position_buffer),
            list_color_buffer: ::core::clone::Clone::clone(&self.list_color_buffer),
            list_vertex_count: ::core::clone::Clone::clone(&self.list_vertex_count),
            strip_position_buffer: ::core::clone::Clone::clone(&self.strip_position_buffer),
            strip_color_buffer: ::core::clone::Clone::clone(&self.strip_color_buffer),
            strip_vertex_count: ::core::clone::Clone::clone(&self.strip_vertex_count),
        }
    }
}Clone)]
247struct GpuLineGizmo {
248    list_position_buffer: Buffer,
249    list_color_buffer: Buffer,
250    list_vertex_count: u32,
251    strip_position_buffer: Buffer,
252    strip_color_buffer: Buffer,
253    strip_vertex_count: u32,
254}
255
256impl RenderAsset for GpuLineGizmo {
257    type SourceAsset = GizmoAsset;
258    type Param = SRes<RenderDevice>;
259
260    fn prepare_asset(
261        gizmo: Self::SourceAsset,
262        _: AssetId<Self::SourceAsset>,
263        render_device: &mut SystemParamItem<Self::Param>,
264        _: Option<&Self>,
265    ) -> Result<Self, PrepareAssetError<Self::SourceAsset>> {
266        let list_position_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
267            usage: BufferUsages::VERTEX,
268            label: Some("LineGizmo Position Buffer"),
269            contents: cast_slice(&gizmo.buffer().list_positions),
270        });
271
272        let list_color_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
273            usage: BufferUsages::VERTEX,
274            label: Some("LineGizmo Color Buffer"),
275            contents: cast_slice(&gizmo.buffer().list_colors),
276        });
277
278        let strip_position_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
279            usage: BufferUsages::VERTEX,
280            label: Some("LineGizmo Strip Position Buffer"),
281            contents: cast_slice(&gizmo.buffer().strip_positions),
282        });
283
284        let strip_color_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
285            usage: BufferUsages::VERTEX,
286            label: Some("LineGizmo Strip Color Buffer"),
287            contents: cast_slice(&gizmo.buffer().strip_colors),
288        });
289
290        Ok(GpuLineGizmo {
291            list_position_buffer,
292            list_color_buffer,
293            list_vertex_count: gizmo.buffer().list_positions.len() as u32,
294            strip_position_buffer,
295            strip_color_buffer,
296            strip_vertex_count: gizmo.buffer().strip_positions.len() as u32,
297        })
298    }
299}
300
301#[derive(impl bevy_ecs::component::Component for LineGizmoUniformBindgroupLayout where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::SparseSet;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        let resource_component_id =
            if let ::core::option::Option::Some(id) =
                    required_components.components_registrator().component_id::<LineGizmoUniformBindgroupLayout>()
                {
                id
            } else {
                required_components.components_registrator().register_component::<LineGizmoUniformBindgroupLayout>()
            };
        required_components.register_required::<bevy_ecs::resource::IsResource>(move
                ||
                bevy_ecs::resource::IsResource::new(resource_component_id));
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}
impl bevy_ecs::resource::Resource for LineGizmoUniformBindgroupLayout where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {}Resource)]
302struct LineGizmoUniformBindgroupLayout {
303    layout: BindGroupLayoutDescriptor,
304}
305
306#[cfg_attr(
307    not(any(feature = "bevy_pbr", feature = "bevy_sprite_render")),
308    expect(
309        dead_code,
310        reason = "fields are unused when bevy_pbr and bevy_sprite_render are both disabled."
311    )
312)]
313#[derive(impl bevy_ecs::component::Component for LineGizmoUniformBindgroup where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::SparseSet;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        let resource_component_id =
            if let ::core::option::Option::Some(id) =
                    required_components.components_registrator().component_id::<LineGizmoUniformBindgroup>()
                {
                id
            } else {
                required_components.components_registrator().register_component::<LineGizmoUniformBindgroup>()
            };
        required_components.register_required::<bevy_ecs::resource::IsResource>(move
                ||
                bevy_ecs::resource::IsResource::new(resource_component_id));
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}
impl bevy_ecs::resource::Resource for LineGizmoUniformBindgroup where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {}Resource)]
314struct LineGizmoUniformBindgroup {
315    bindgroup: BindGroup,
316}
317
318fn prepare_line_gizmo_bind_group(
319    mut commands: Commands,
320    line_gizmo_uniform_layout: Res<LineGizmoUniformBindgroupLayout>,
321    render_device: Res<RenderDevice>,
322    pipeline_cache: Res<PipelineCache>,
323    line_gizmo_uniforms: Res<ComponentUniforms<LineGizmoUniform>>,
324) {
325    let Some(line_gizmo_binding) = line_gizmo_uniforms.uniforms().binding() else {
326        return;
327    };
328
329    commands.insert_resource(LineGizmoUniformBindgroup {
330        bindgroup: render_device.create_bind_group(
331            "LineGizmoUniform bindgroup",
332            &pipeline_cache.get_bind_group_layout(&line_gizmo_uniform_layout.layout),
333            &BindGroupEntries::single(line_gizmo_binding),
334        ),
335    });
336}
337
338#[cfg_attr(
339    not(any(feature = "bevy_pbr", feature = "bevy_sprite_render")),
340    expect(
341        dead_code,
342        reason = "struct is not constructed when bevy_pbr and bevy_sprite_render are both disabled."
343    )
344)]
345struct SetLineGizmoBindGroup<const I: usize>;
346
347impl<const I: usize, P: PhaseItem> RenderCommand<P> for SetLineGizmoBindGroup<I> {
348    type Param = SRes<LineGizmoUniformBindgroup>;
349    type ViewQuery = ();
350    type ItemQuery = Read<DynamicUniformIndex<LineGizmoUniform>>;
351
352    #[inline]
353    fn render<'w>(
354        _item: &P,
355        _view: ROQueryItem<'w, '_, Self::ViewQuery>,
356        uniform_index: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
357        bind_group: SystemParamItem<'w, '_, Self::Param>,
358        pass: &mut TrackedRenderPass<'w>,
359    ) -> RenderCommandResult {
360        let Some(uniform_index) = uniform_index else {
361            return RenderCommandResult::Skip;
362        };
363        pass.set_bind_group(
364            I,
365            &bind_group.into_inner().bindgroup,
366            &[uniform_index.index()],
367        );
368        RenderCommandResult::Success
369    }
370}
371
372#[cfg_attr(
373    not(any(feature = "bevy_pbr", feature = "bevy_sprite_render")),
374    expect(
375        dead_code,
376        reason = "struct is not constructed when bevy_pbr and bevy_sprite_render are both disabled."
377    )
378)]
379struct DrawLineGizmo<const STRIP: bool>;
380
381impl<P: PhaseItem, const STRIP: bool> RenderCommand<P> for DrawLineGizmo<STRIP> {
382    type Param = SRes<RenderAssets<GpuLineGizmo>>;
383    type ViewQuery = ();
384    type ItemQuery = Read<GizmoMeshConfig>;
385
386    #[inline]
387    fn render<'w>(
388        _item: &P,
389        _view: ROQueryItem<'w, '_, Self::ViewQuery>,
390        config: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
391        line_gizmos: SystemParamItem<'w, '_, Self::Param>,
392        pass: &mut TrackedRenderPass<'w>,
393    ) -> RenderCommandResult {
394        let Some(config) = config else {
395            return RenderCommandResult::Skip;
396        };
397        let Some(line_gizmo) = line_gizmos.into_inner().get(&config.handle) else {
398            return RenderCommandResult::Skip;
399        };
400
401        let vertex_count = if STRIP {
402            line_gizmo.strip_vertex_count
403        } else {
404            line_gizmo.list_vertex_count
405        };
406
407        if vertex_count < 2 {
408            return RenderCommandResult::Success;
409        }
410
411        let instances = if STRIP {
412            let item_size = VertexFormat::Float32x3.size();
413            let buffer_size = line_gizmo.strip_position_buffer.size() - item_size;
414
415            pass.set_vertex_buffer(0, line_gizmo.strip_position_buffer.slice(..buffer_size));
416            pass.set_vertex_buffer(1, line_gizmo.strip_position_buffer.slice(item_size..));
417
418            let item_size = VertexFormat::Float32x4.size();
419            let buffer_size = line_gizmo.strip_color_buffer.size() - item_size;
420
421            pass.set_vertex_buffer(2, line_gizmo.strip_color_buffer.slice(..buffer_size));
422            pass.set_vertex_buffer(3, line_gizmo.strip_color_buffer.slice(item_size..));
423
424            vertex_count - 1
425        } else {
426            pass.set_vertex_buffer(0, line_gizmo.list_position_buffer.slice(..));
427            pass.set_vertex_buffer(1, line_gizmo.list_color_buffer.slice(..));
428
429            vertex_count / 2
430        };
431
432        pass.draw(0..6, 0..instances);
433
434        RenderCommandResult::Success
435    }
436}
437
438#[cfg_attr(
439    not(any(feature = "bevy_pbr", feature = "bevy_sprite_render")),
440    expect(
441        dead_code,
442        reason = "struct is not constructed when bevy_pbr and bevy_sprite_render are both disabled."
443    )
444)]
445struct DrawLineJointGizmo;
446
447impl<P: PhaseItem> RenderCommand<P> for DrawLineJointGizmo {
448    type Param = SRes<RenderAssets<GpuLineGizmo>>;
449    type ViewQuery = ();
450    type ItemQuery = Read<GizmoMeshConfig>;
451
452    #[inline]
453    fn render<'w>(
454        _item: &P,
455        _view: ROQueryItem<'w, '_, Self::ViewQuery>,
456        config: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
457        line_gizmos: SystemParamItem<'w, '_, Self::Param>,
458        pass: &mut TrackedRenderPass<'w>,
459    ) -> RenderCommandResult {
460        let Some(config) = config else {
461            return RenderCommandResult::Skip;
462        };
463        let Some(line_gizmo) = line_gizmos.into_inner().get(&config.handle) else {
464            return RenderCommandResult::Skip;
465        };
466
467        if line_gizmo.strip_vertex_count <= 2 {
468            return RenderCommandResult::Success;
469        };
470
471        if config.line_joints == GizmoLineJoint::None {
472            return RenderCommandResult::Success;
473        };
474
475        let instances = {
476            let item_size = VertexFormat::Float32x3.size();
477            // position_a
478            let buffer_size_a = line_gizmo.strip_position_buffer.size() - item_size * 2;
479            pass.set_vertex_buffer(0, line_gizmo.strip_position_buffer.slice(..buffer_size_a));
480            // position_b
481            let buffer_size_b = line_gizmo.strip_position_buffer.size() - item_size;
482            pass.set_vertex_buffer(
483                1,
484                line_gizmo
485                    .strip_position_buffer
486                    .slice(item_size..buffer_size_b),
487            );
488            // position_c
489            pass.set_vertex_buffer(2, line_gizmo.strip_position_buffer.slice(item_size * 2..));
490
491            // color
492            let item_size = VertexFormat::Float32x4.size();
493            let buffer_size = line_gizmo.strip_color_buffer.size() - item_size;
494            // This corresponds to the color of position_b, hence starts from `item_size`
495            pass.set_vertex_buffer(
496                3,
497                line_gizmo.strip_color_buffer.slice(item_size..buffer_size),
498            );
499
500            line_gizmo.strip_vertex_count - 2
501        };
502
503        let vertices = match config.line_joints {
504            GizmoLineJoint::None => ::core::panicking::unreachable_default_msg()unreachable!(),
505            GizmoLineJoint::Miter => 6,
506            GizmoLineJoint::Round(resolution) => resolution * 3,
507            GizmoLineJoint::Bevel => 3,
508        };
509
510        pass.draw(0..vertices, 0..instances);
511
512        RenderCommandResult::Success
513    }
514}
515
516#[cfg_attr(
517    not(any(feature = "bevy_pbr", feature = "bevy_sprite_render")),
518    expect(
519        dead_code,
520        reason = "function is unused when bevy_pbr and bevy_sprite_render are both disabled."
521    )
522)]
523fn line_gizmo_vertex_buffer_layouts(strip: bool) -> Vec<VertexBufferLayout> {
524    use VertexFormat::*;
525    let mut position_layout = VertexBufferLayout {
526        array_stride: Float32x3.size(),
527        step_mode: VertexStepMode::Instance,
528        attributes: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [VertexAttribute {
                    format: Float32x3,
                    offset: 0,
                    shader_location: 0,
                }]))vec![VertexAttribute {
529            format: Float32x3,
530            offset: 0,
531            shader_location: 0,
532        }],
533    };
534
535    let mut color_layout = VertexBufferLayout {
536        array_stride: Float32x4.size(),
537        step_mode: VertexStepMode::Instance,
538        attributes: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [VertexAttribute {
                    format: Float32x4,
                    offset: 0,
                    shader_location: 2,
                }]))vec![VertexAttribute {
539            format: Float32x4,
540            offset: 0,
541            shader_location: 2,
542        }],
543    };
544
545    if strip {
546        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [position_layout.clone(),
                {
                    position_layout.attributes[0].shader_location = 1;
                    position_layout
                }, color_layout.clone(),
                {
                    color_layout.attributes[0].shader_location = 3;
                    color_layout
                }]))vec![
547            position_layout.clone(),
548            {
549                position_layout.attributes[0].shader_location = 1;
550                position_layout
551            },
552            color_layout.clone(),
553            {
554                color_layout.attributes[0].shader_location = 3;
555                color_layout
556            },
557        ]
558    } else {
559        position_layout.array_stride *= 2;
560        position_layout.attributes.push(VertexAttribute {
561            format: Float32x3,
562            offset: Float32x3.size(),
563            shader_location: 1,
564        });
565
566        color_layout.array_stride *= 2;
567        color_layout.attributes.push(VertexAttribute {
568            format: Float32x4,
569            offset: Float32x4.size(),
570            shader_location: 3,
571        });
572
573        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [position_layout, color_layout]))vec![position_layout, color_layout]
574    }
575}
576
577#[cfg_attr(
578    not(any(feature = "bevy_pbr", feature = "bevy_sprite_render")),
579    expect(
580        dead_code,
581        reason = "function is unused when bevy_pbr and bevy_sprite_render are both disabled."
582    )
583)]
584fn line_joint_gizmo_vertex_buffer_layouts() -> Vec<VertexBufferLayout> {
585    use VertexFormat::*;
586    let mut position_layout = VertexBufferLayout {
587        array_stride: Float32x3.size(),
588        step_mode: VertexStepMode::Instance,
589        attributes: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [VertexAttribute {
                    format: Float32x3,
                    offset: 0,
                    shader_location: 0,
                }]))vec![VertexAttribute {
590            format: Float32x3,
591            offset: 0,
592            shader_location: 0,
593        }],
594    };
595
596    let color_layout = VertexBufferLayout {
597        array_stride: Float32x4.size(),
598        step_mode: VertexStepMode::Instance,
599        attributes: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [VertexAttribute {
                    format: Float32x4,
                    offset: 0,
                    shader_location: 3,
                }]))vec![VertexAttribute {
600            format: Float32x4,
601            offset: 0,
602            shader_location: 3,
603        }],
604    };
605
606    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [position_layout.clone(),
                {
                    position_layout.attributes[0].shader_location = 1;
                    position_layout.clone()
                },
                {
                    position_layout.attributes[0].shader_location = 2;
                    position_layout
                }, color_layout.clone()]))vec![
607        position_layout.clone(),
608        {
609            position_layout.attributes[0].shader_location = 1;
610            position_layout.clone()
611        },
612        {
613            position_layout.attributes[0].shader_location = 2;
614            position_layout
615        },
616        color_layout.clone(),
617    ]
618}
619
620/// Holds entities that the gizmo render phase items are associated with.
621///
622/// Sorted render phases require each phase item to be associated with an entity
623/// in the main world. Immediate mode gizmos don't have entities normally, so we
624/// need to create entities for them. There are three potential phase items that
625/// can be added and therefore three potential entities.
626#[derive(#[automatically_derived]impl ::core::clone::Clone for LineGizmoEntities {
    #[inline]
    fn clone(&self) -> Self {
        LineGizmoEntities {
            line_gizmo_renderer: ::core::clone::Clone::clone(&self.line_gizmo_renderer),
            line_strip_gizmo_renderer: ::core::clone::Clone::clone(&self.line_strip_gizmo_renderer),
            line_joint_gizmo_renderer: ::core::clone::Clone::clone(&self.line_joint_gizmo_renderer),
        }
    }
}Clone, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for LineGizmoEntities where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.register_type_data_with::<ReflectResource, Self,
                    _>(());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <MainEntity as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for LineGizmoEntities where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<MainEntity>("line_gizmo_renderer"),
                                                bevy_reflect::NamedField::new::<MainEntity>("line_strip_gizmo_renderer"),
                                                bevy_reflect::NamedField::new::<MainEntity>("line_joint_gizmo_renderer")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for LineGizmoEntities where  {
            fn type_path() -> &'static str {
                "bevy_gizmos_render::LineGizmoEntities"
            }
            fn short_type_path() -> &'static str { "LineGizmoEntities" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("LineGizmoEntities")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_gizmos_render".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_gizmos_render")
            }
        }
        impl bevy_reflect::Reflect for LineGizmoEntities where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<LineGizmoEntities
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for LineGizmoEntities where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "line_gizmo_renderer" =>
                        ::core::option::Option::Some(&self.line_gizmo_renderer),
                    "line_strip_gizmo_renderer" =>
                        ::core::option::Option::Some(&self.line_strip_gizmo_renderer),
                    "line_joint_gizmo_renderer" =>
                        ::core::option::Option::Some(&self.line_joint_gizmo_renderer),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "line_gizmo_renderer" =>
                        ::core::option::Option::Some(&mut self.line_gizmo_renderer),
                    "line_strip_gizmo_renderer" =>
                        ::core::option::Option::Some(&mut self.line_strip_gizmo_renderer),
                    "line_joint_gizmo_renderer" =>
                        ::core::option::Option::Some(&mut self.line_joint_gizmo_renderer),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize =>
                        ::core::option::Option::Some(&self.line_gizmo_renderer),
                    1usize =>
                        ::core::option::Option::Some(&self.line_strip_gizmo_renderer),
                    2usize =>
                        ::core::option::Option::Some(&self.line_joint_gizmo_renderer),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize =>
                        ::core::option::Option::Some(&mut self.line_gizmo_renderer),
                    1usize =>
                        ::core::option::Option::Some(&mut self.line_strip_gizmo_renderer),
                    2usize =>
                        ::core::option::Option::Some(&mut self.line_joint_gizmo_renderer),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize =>
                        ::core::option::Option::Some("line_gizmo_renderer"),
                    1usize =>
                        ::core::option::Option::Some("line_strip_gizmo_renderer"),
                    2usize =>
                        ::core::option::Option::Some("line_joint_gizmo_renderer"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "line_gizmo_renderer" =>
                        ::core::option::Option::Some(0usize),
                    "line_strip_gizmo_renderer" =>
                        ::core::option::Option::Some(1usize),
                    "line_joint_gizmo_renderer" =>
                        ::core::option::Option::Some(2usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 3usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::structs::DynamicStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("line_gizmo_renderer",
                    bevy_reflect::PartialReflect::to_dynamic(&self.line_gizmo_renderer)?);
                dynamic.insert_boxed("line_strip_gizmo_renderer",
                    bevy_reflect::PartialReflect::to_dynamic(&self.line_strip_gizmo_renderer)?);
                dynamic.insert_boxed("line_joint_gizmo_renderer",
                    bevy_reflect::PartialReflect::to_dynamic(&self.line_joint_gizmo_renderer)?);
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl bevy_reflect::PartialReflect for LineGizmoEntities where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
            }
        }
        impl bevy_reflect::FromReflect for LineGizmoEntities where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            line_gizmo_renderer: <MainEntity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "line_gizmo_renderer")?)?,
                            line_strip_gizmo_renderer: <MainEntity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "line_strip_gizmo_renderer")?)?,
                            line_joint_gizmo_renderer: <MainEntity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "line_joint_gizmo_renderer")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect, impl bevy_ecs::component::Component for LineGizmoEntities where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::SparseSet;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        let resource_component_id =
            if let ::core::option::Option::Some(id) =
                    required_components.components_registrator().component_id::<LineGizmoEntities>()
                {
                id
            } else {
                required_components.components_registrator().register_component::<LineGizmoEntities>()
            };
        required_components.register_required::<bevy_ecs::resource::IsResource>(move
                ||
                bevy_ecs::resource::IsResource::new(resource_component_id));
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}
impl bevy_ecs::resource::Resource for LineGizmoEntities where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {}Resource, impl bevy_extract::extract_resource::ExtractResource<RenderApp> for
    LineGizmoEntities where Self: ::core::clone::Clone {
    type Source = Self;
    fn extract_resource(source: &Self::Source) -> Self { source.clone() }
}ExtractResource)]
627#[reflect(Clone, Resource)]
628#[extract_app(RenderApp)]
629pub struct LineGizmoEntities {
630    /// An entity that regular line phase items are associated with.
631    pub line_gizmo_renderer: MainEntity,
632    /// An entity that line strip phase items are associated with.
633    pub line_strip_gizmo_renderer: MainEntity,
634    /// An entity that line joint phase items are associated with.
635    pub line_joint_gizmo_renderer: MainEntity,
636}
637
638impl FromWorld for LineGizmoEntities {
639    fn from_world(world: &mut World) -> LineGizmoEntities {
640        // Create the entities for line gizmo phase items to be associated with.
641        let line_gizmo_renderer = world.spawn(Name::new("LineGizmoRenderer")).id();
642        let line_strip_gizmo_renderer = world.spawn(Name::new("LineStripGizmoRenderer")).id();
643        let line_joint_gizmo_renderer = world.spawn(Name::new("LineJointGizmoRenderer")).id();
644        LineGizmoEntities {
645            line_gizmo_renderer: MainEntity::from(line_gizmo_renderer),
646            line_strip_gizmo_renderer: MainEntity::from(line_strip_gizmo_renderer),
647            line_joint_gizmo_renderer: MainEntity::from(line_joint_gizmo_renderer),
648        }
649    }
650}