1- use bevy:: { mesh :: MeshVertexAttribute , prelude:: * } ;
1+ use bevy:: prelude:: * ;
22
3- use super :: { Attribute , BuiltinAttributes } ;
3+ use super :: BuiltinAttributes ;
44
55// bevy requires an attribute id for each unique vertex attribute. we don't really want to
66// expose this to users, so we hash the attribute name to generate a unique id. in theory
@@ -18,18 +18,9 @@ pub const fn hash_attr_name(s: &str) -> u64 {
1818 hash
1919}
2020
21- /// Describes the layout of vertex attributes within a mesh's vertex buffer.
22- #[ derive( Component , Clone , Debug ) ]
21+ #[ derive( Component , Clone , Debug , Default ) ]
2322pub struct VertexLayout {
24- attributes : Vec < VertexAttribute > ,
25- }
26-
27- /// Represents a single vertex attribute within a vertex layout, including its type and offset
28- /// within the vertex buffer.
29- #[ derive( Clone , Debug ) ]
30- pub struct VertexAttribute {
31- pub attribute : MeshVertexAttribute ,
32- pub offset : u64 ,
23+ attributes : Vec < Entity > ,
3324}
3425
3526impl VertexLayout {
@@ -39,171 +30,67 @@ impl VertexLayout {
3930 }
4031 }
4132
42- pub fn default_layout ( ) -> Self {
43- let attrs = [
44- Mesh :: ATTRIBUTE_POSITION ,
45- Mesh :: ATTRIBUTE_NORMAL ,
46- Mesh :: ATTRIBUTE_COLOR ,
47- Mesh :: ATTRIBUTE_UV_0 ,
48- ] ;
49-
50- let mut offset = 0u64 ;
51- let mut layout_attrs = Vec :: with_capacity ( attrs. len ( ) ) ;
52-
53- for attr in attrs {
54- let size = attr. format . size ( ) ;
55- layout_attrs. push ( VertexAttribute {
56- attribute : attr,
57- offset,
58- } ) ;
59- offset += size;
60- }
61-
62- Self {
63- attributes : layout_attrs,
64- }
33+ pub fn with_attributes ( attrs : Vec < Entity > ) -> Self {
34+ Self { attributes : attrs }
6535 }
6636
67- pub fn attributes ( & self ) -> & [ VertexAttribute ] {
37+ pub fn attributes ( & self ) -> & [ Entity ] {
6838 & self . attributes
6939 }
7040
71- pub fn has_attribute ( & self , attr : & MeshVertexAttribute ) -> bool {
72- self . attributes . iter ( ) . any ( |a| a . attribute . id == attr. id )
41+ pub fn push ( & mut self , attr : Entity ) {
42+ self . attributes . push ( attr) ;
7343 }
74- }
75-
76- impl Default for VertexLayout {
77- fn default ( ) -> Self {
78- Self :: default_layout ( )
79- }
80- }
81-
82- bitflags:: bitflags! {
83- #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
84- pub struct VertexAttributes : u32 {
85- const POSITION = 0x01 ;
86- const NORMAL = 0x02 ;
87- const COLOR = 0x04 ;
88- const UV = 0x08 ;
89- }
90- }
91-
92- impl VertexAttributes {
93- pub fn to_layout ( self ) -> VertexLayout {
94- let mut attrs = vec ! [ Mesh :: ATTRIBUTE_POSITION ] ;
95-
96- if self . contains ( VertexAttributes :: NORMAL ) {
97- attrs. push ( Mesh :: ATTRIBUTE_NORMAL ) ;
98- }
99- if self . contains ( VertexAttributes :: COLOR ) {
100- attrs. push ( Mesh :: ATTRIBUTE_COLOR ) ;
101- }
102- if self . contains ( VertexAttributes :: UV ) {
103- attrs. push ( Mesh :: ATTRIBUTE_UV_0 ) ;
104- }
105-
106- let mut offset = 0u64 ;
107- let mut layout_attrs = Vec :: with_capacity ( attrs. len ( ) ) ;
10844
109- for attr in attrs {
110- let size = attr. format . size ( ) ;
111- layout_attrs. push ( VertexAttribute {
112- attribute : attr,
113- offset,
114- } ) ;
115- offset += size;
116- }
117-
118- VertexLayout {
119- attributes : layout_attrs,
120- }
45+ pub fn has_attribute ( & self , attr_entity : Entity ) -> bool {
46+ self . attributes . contains ( & attr_entity)
12147 }
12248}
12349
124- #[ derive( Component , Clone , Debug , Default ) ]
125- pub struct VertexLayoutBuilder {
126- attributes : Vec < Entity > ,
50+ pub fn create ( In ( ( ) ) : In < ( ) > , mut commands : Commands ) -> Entity {
51+ commands. spawn ( VertexLayout :: new ( ) ) . id ( )
12752}
12853
129- pub fn create ( In ( ( ) ) : In < ( ) > , mut commands : Commands ) -> Entity {
130- commands. spawn ( VertexLayoutBuilder :: default ( ) ) . id ( )
54+ pub fn create_default ( world : & mut World ) -> Entity {
55+ let builtins = world. resource :: < BuiltinAttributes > ( ) ;
56+ let attrs = vec ! [ builtins. position, builtins. normal, builtins. color, builtins. uv] ;
57+ world. spawn ( VertexLayout :: with_attributes ( attrs) ) . id ( )
13158}
13259
13360pub fn add_position ( world : & mut World , entity : Entity ) {
134- let builtins = world. resource :: < BuiltinAttributes > ( ) ;
135- let position = builtins. position ;
136- if let Some ( mut builder) = world. get_mut :: < VertexLayoutBuilder > ( entity) {
137- builder. attributes . push ( position) ;
61+ let position = world. resource :: < BuiltinAttributes > ( ) . position ;
62+ if let Some ( mut layout) = world. get_mut :: < VertexLayout > ( entity) {
63+ layout. push ( position) ;
13864 }
13965}
14066
14167pub fn add_normal ( world : & mut World , entity : Entity ) {
142- let builtins = world. resource :: < BuiltinAttributes > ( ) ;
143- let normal = builtins. normal ;
144- if let Some ( mut builder) = world. get_mut :: < VertexLayoutBuilder > ( entity) {
145- builder. attributes . push ( normal) ;
68+ let normal = world. resource :: < BuiltinAttributes > ( ) . normal ;
69+ if let Some ( mut layout) = world. get_mut :: < VertexLayout > ( entity) {
70+ layout. push ( normal) ;
14671 }
14772}
14873
14974pub fn add_color ( world : & mut World , entity : Entity ) {
150- let builtins = world. resource :: < BuiltinAttributes > ( ) ;
151- let color = builtins. color ;
152- if let Some ( mut builder) = world. get_mut :: < VertexLayoutBuilder > ( entity) {
153- builder. attributes . push ( color) ;
75+ let color = world. resource :: < BuiltinAttributes > ( ) . color ;
76+ if let Some ( mut layout) = world. get_mut :: < VertexLayout > ( entity) {
77+ layout. push ( color) ;
15478 }
15579}
15680
15781pub fn add_uv ( world : & mut World , entity : Entity ) {
158- let builtins = world. resource :: < BuiltinAttributes > ( ) ;
159- let uv = builtins. uv ;
160- if let Some ( mut builder) = world. get_mut :: < VertexLayoutBuilder > ( entity) {
161- builder. attributes . push ( uv) ;
82+ let uv = world. resource :: < BuiltinAttributes > ( ) . uv ;
83+ if let Some ( mut layout) = world. get_mut :: < VertexLayout > ( entity) {
84+ layout. push ( uv) ;
16285 }
16386}
16487
16588pub fn add_attribute ( world : & mut World , layout_entity : Entity , attr_entity : Entity ) {
166- if let Some ( mut builder ) = world. get_mut :: < VertexLayoutBuilder > ( layout_entity) {
167- builder . attributes . push ( attr_entity) ;
89+ if let Some ( mut layout ) = world. get_mut :: < VertexLayout > ( layout_entity) {
90+ layout . push ( attr_entity) ;
16891 }
16992}
17093
17194pub fn destroy ( In ( entity) : In < Entity > , mut commands : Commands ) {
17295 commands. entity ( entity) . despawn ( ) ;
17396}
174-
175- pub fn build (
176- In ( entity) : In < Entity > ,
177- mut commands : Commands ,
178- builders : Query < & VertexLayoutBuilder > ,
179- attrs : Query < & Attribute > ,
180- ) -> bool {
181- let Ok ( builder) = builders. get ( entity) else {
182- return false ;
183- } ;
184-
185- let mut offset = 0u64 ;
186- let mut layout_attrs = Vec :: with_capacity ( builder. attributes . len ( ) ) ;
187-
188- for & attr_entity in & builder. attributes {
189- let Ok ( attr) = attrs. get ( attr_entity) else {
190- return false ;
191- } ;
192- let size = attr. inner . format . size ( ) ;
193- layout_attrs. push ( VertexAttribute {
194- attribute : attr. inner . clone ( ) ,
195- offset,
196- } ) ;
197- offset += size;
198- }
199-
200- let layout = VertexLayout {
201- attributes : layout_attrs,
202- } ;
203-
204- commands
205- . entity ( entity)
206- . remove :: < VertexLayoutBuilder > ( )
207- . insert ( layout) ;
208- true
209- }
0 commit comments