@@ -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 } ;
@@ -738,7 +738,7 @@ fn extract_mesh_vertices_indices(mesh: &Mesh) -> Option<(Vec<na::Point3<Real>>,
738
738
use rapier:: na:: point;
739
739
740
740
let vertices = mesh. attribute ( Mesh :: ATTRIBUTE_POSITION ) ?;
741
- let indices = mesh. indices ( ) ? ;
741
+ let indices = mesh. indices ( ) ;
742
742
743
743
let vtx: Vec < _ > = match vertices {
744
744
VertexAttributeValues :: Float32 ( vtx) => Some (
@@ -755,11 +755,40 @@ fn extract_mesh_vertices_indices(mesh: &Mesh) -> Option<(Vec<na::Point3<Real>>,
755
755
} ?;
756
756
757
757
let idx = match indices {
758
- Indices :: U16 ( idx) => idx
758
+ Some ( Indices :: U16 ( idx) ) => idx
759
759
. chunks_exact ( 3 )
760
760
. map ( |i| [ i[ 0 ] as u32 , i[ 1 ] as u32 , i[ 2 ] as u32 ] )
761
761
. 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
+ }
763
792
} ;
764
793
765
794
Some ( ( vtx, idx) )
0 commit comments