@@ -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 } ;
@@ -740,7 +740,7 @@ fn extract_mesh_vertices_indices(mesh: &Mesh) -> Option<(Vec<na::Point3<Real>>,
740740 use rapier:: na:: point;
741741
742742 let vertices = mesh. attribute ( Mesh :: ATTRIBUTE_POSITION ) ?;
743- let indices = mesh. indices ( ) ? ;
743+ let indices = mesh. indices ( ) ;
744744
745745 let vtx: Vec < _ > = match vertices {
746746 VertexAttributeValues :: Float32 ( vtx) => Some (
@@ -757,11 +757,40 @@ fn extract_mesh_vertices_indices(mesh: &Mesh) -> Option<(Vec<na::Point3<Real>>,
757757 } ?;
758758
759759 let idx = match indices {
760- Indices :: U16 ( idx) => idx
760+ Some ( Indices :: U16 ( idx) ) => idx
761761 . chunks_exact ( 3 )
762762 . map ( |i| [ i[ 0 ] as u32 , i[ 1 ] as u32 , i[ 2 ] as u32 ] )
763763 . collect ( ) ,
764- Indices :: U32 ( idx) => idx. chunks_exact ( 3 ) . map ( |i| [ i[ 0 ] , i[ 1 ] , i[ 2 ] ] ) . collect ( ) ,
764+ Some ( Indices :: U32 ( idx) ) => idx. chunks_exact ( 3 ) . map ( |i| [ i[ 0 ] , i[ 1 ] , i[ 2 ] ] ) . collect ( ) ,
765+ None => {
766+ // Meshes loaded from glTF files may not necessarily have an index buffer
767+ // in order to save memory (e.g. files generated by osm2world), in which case
768+ // there's predefined algorithm to calculate indices for each topology.
769+ match mesh. primitive_topology ( ) {
770+ PrimitiveTopology :: TriangleList => {
771+ // [[0, 1, 2], [3, 4, 5], [6, 7, 8], ...]
772+ ( 0 ..vtx. len ( ) as u32 )
773+ . step_by ( 3 )
774+ . map ( |i| [ i, i + 1 , i + 2 ] )
775+ . collect ( )
776+ }
777+ PrimitiveTopology :: TriangleStrip => {
778+ // [[0, 1, 2], [2, 1, 3], [2, 3, 4], ...]
779+ ( 0 ..vtx. len ( ) as u32 - 2 )
780+ . map ( |i| {
781+ if i % 2 == 0 {
782+ [ i, i + 1 , i + 2 ]
783+ } else {
784+ [ i + 1 , i, i + 2 ]
785+ }
786+ } )
787+ . collect ( )
788+ }
789+ // ignore PointList, LineList, LineStrip:
790+ // they don't have meaningful colliders
791+ _ => return None ,
792+ }
793+ }
765794 } ;
766795
767796 Some ( ( vtx, idx) )
0 commit comments