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