@@ -3,7 +3,7 @@ use na::DVector;
33#[ cfg( all( feature = "dim3" , feature = "async-collider" ) ) ]
44use {
55 bevy:: prelude:: * ,
6- bevy:: render:: mesh:: { Indices , VertexAttributeValues } ,
6+ bevy:: render:: mesh:: { Indices , PrimitiveTopology , VertexAttributeValues } ,
77} ;
88
99use rapier:: prelude:: { FeatureId , Point , Ray , SharedShape , Vector , DIM } ;
@@ -738,7 +738,7 @@ fn extract_mesh_vertices_indices(mesh: &Mesh) -> Option<(Vec<na::Point3<Real>>,
738738 use rapier:: na:: point;
739739
740740 let vertices = mesh. attribute ( Mesh :: ATTRIBUTE_POSITION ) ?;
741- let indices = mesh. indices ( ) ? ;
741+ let indices = mesh. indices ( ) ;
742742
743743 let vtx: Vec < _ > = match vertices {
744744 VertexAttributeValues :: Float32 ( vtx) => Some (
@@ -755,11 +755,40 @@ fn extract_mesh_vertices_indices(mesh: &Mesh) -> Option<(Vec<na::Point3<Real>>,
755755 } ?;
756756
757757 let idx = match indices {
758- Indices :: U16 ( idx) => idx
758+ Some ( Indices :: U16 ( idx) ) => idx
759759 . chunks_exact ( 3 )
760760 . map ( |i| [ i[ 0 ] as u32 , i[ 1 ] as u32 , i[ 2 ] as u32 ] )
761761 . collect ( ) ,
762- Indices :: U32 ( idx) => idx. chunks_exact ( 3 ) . map ( |i| [ i[ 0 ] , i[ 1 ] , i[ 2 ] ] ) . collect ( ) ,
762+ Some ( Indices :: U32 ( idx) ) => idx. chunks_exact ( 3 ) . map ( |i| [ i[ 0 ] , i[ 1 ] , i[ 2 ] ] ) . collect ( ) ,
763+ None => {
764+ // Meshes loaded from glTF files may not necessarily have an index buffer
765+ // in order to save memory (e.g. files generated by osm2world), in which case
766+ // there's predefined algorithm to calculate indices for each topology.
767+ match mesh. primitive_topology ( ) {
768+ PrimitiveTopology :: TriangleList => {
769+ // [[0, 1, 2], [3, 4, 5], [6, 7, 8], ...]
770+ ( 0 ..vtx. len ( ) as u32 )
771+ . step_by ( 3 )
772+ . map ( |i| [ i, i + 1 , i + 2 ] )
773+ . collect ( )
774+ }
775+ PrimitiveTopology :: TriangleStrip => {
776+ // [[0, 1, 2], [2, 1, 3], [2, 3, 4], ...]
777+ ( 0 ..vtx. len ( ) as u32 - 2 )
778+ . map ( |i| {
779+ if i % 2 == 0 {
780+ [ i, i + 1 , i + 2 ]
781+ } else {
782+ [ i + 1 , i, i + 2 ]
783+ }
784+ } )
785+ . collect ( )
786+ }
787+ // ignore PointList, LineList, LineStrip:
788+ // they don't have meaningful colliders
789+ _ => return None ,
790+ }
791+ }
763792 } ;
764793
765794 Some ( ( vtx, idx) )
0 commit comments