/// For now only use the first object in the obj file.
/// Returns (vertices, vertex_indicies, texture_coordinate indices)
For now only use the first object in the obj file.
For now only use the first object in the obj file .
fn load_obj_models(obj_file_path: &str) -> (Vec<DefaultForwardShaderVertex>, Option<Vec<u32>>) {
  let mut model_file = File::open(obj_file_path).unwrap();
  let mut model_file_text = String::new();
  model_file.read_to_string(&mut model_file_text).unwrap();
  let obj_set = obj::obj::parse(&model_file_text).unwrap();
  if obj_set.objects.len() != 1 {
    panic!(
      "The model you attempted to load has more than one object in it, implying it is a scene, if \
       you wish to use it as a single model, modify the application code to ignore that or join \
       your meshes into a single model"
    );
  }
  info!("Loaded model {}", OBJ_MODEL_FILE_NAME);
  let mut vertices: Vec<DefaultForwardShaderVertex> = Vec::new();
  let mut indices: Vec<u32> = Vec::new();
  // Map of inserted (obj_vertex_index, obj_texture_index) to index in the
  // vertices array im building.
  let mut inserted_indices: HashMap<(usize, usize), usize> = HashMap::new();
  let model_vertices = &obj_set.objects[0].vertices;
  for geo in obj_set.objects[0].geometry.iter() {
    // For every set of geometry (regardless of material for now).
    for shape in geo.shapes.iter() {
      // For every face/shape in the set of geometry.
      match shape.primitive {
        obj::obj::Primitive::Triangle(x, y, z) => {
          for &vert in [x, y, z].iter() {
            // We're only building a buffer of indices and vertices which contain position
            // and tex coord.
            let index_key = (vert.0, vert.1.unwrap());
            if let Some(&vtx_index) = inserted_indices.get(&index_key) {
              // Already loaded this (vertex index, texture index) combo, just add it to the
              // index buffer.
              indices.push(vtx_index as _);
              continue;
            }
            // This is a new unique vertex (where a vertex is both a position and it's
            // texture coordinate) so add it to the vertex buffer and the index buffer.
            let current_vertex = model_vertices[vert.0];
            let vertex_as_float = [
              current_vertex.x as f32,
              current_vertex.y as f32,
              current_vertex.z as f32,
            ];
            let texture_vertices = &obj_set.objects[0].tex_vertices;
            let tex_vertex = texture_vertices[vert.1.unwrap()];
            // TODO BACKENDS only flip on coordinate systems that should.
            let texture_vertex_as_float = [tex_vertex.u as f32, 1f32 - tex_vertex.v as f32];
            // Ignoring normals, there is no shading in this example.
            // Keep track of which keys were inserted and add this vertex to the index
            // buffer.
            inserted_indices.insert(index_key, vertices.len());
            indices.push(vertices.len() as _);
            // Add to the vertex buffer.
            vertices.push(DefaultForwardShaderVertex::new_with_texture(
              &vertex_as_float,
              &texture_vertex_as_float,
            ));
          }
        }
        _ => warn!("Unsupported primitive!"),
      }
    }
  }
  info!(
    "Vertices/indices in model: {}, {}",
    vertices.len(),
    indices.len()
  );
  (vertices, Some(indices))
}
fn load_obj_models ( obj_file_path : & str ) -> ( Vec < DefaultForwardShaderVertex > , Option < Vec < u32 > > ) { let mut model_file = File :: open ( obj_file_path ) . unwrap ( ) ; let mut model_file_text = String :: new ( ) ; model_file . read_to_string ( & mut model_file_text ) . unwrap ( ) ; let obj_set = obj :: obj :: parse ( & model_file_text ) . unwrap ( ) ; if obj_set . objects . len ( ) != 1 { panic ! ( " \
 \
 " ) ; } info ! ( " " OBJ_MODEL_FILE_NAME ) ; let mut vertices : Vec < DefaultForwardShaderVertex > = Vec :: new ( ) ; let mut indices : Vec < u32 > = Vec :: new ( ) ; // Map of inserted (obj_vertex_index, obj_texture_index) to index in the // vertices array im building. let mut inserted_indices : HashMap < ( usize , usize ) , usize > = HashMap :: new ( ) ; let model_vertices = & obj_set . objects [ 0 ] . vertices ; for geo in obj_set . objects [ 0 ] . geometry . iter ( ) { // For every set of geometry (regardless of material for now). for shape in geo . shapes . iter ( ) { // For every face/shape in the set of geometry. match shape . primitive { obj :: obj :: Primitive :: Triangle ( x , y , z ) => { for & vert in [ x , y , z ] . iter ( ) { // We're only building a buffer of indices and vertices which contain position // and tex coord. let index_key = ( vert . 0 , vert . 1 . unwrap ( ) ) ; if let Some ( & vtx_index ) = inserted_indices . get ( & index_key ) { // Already loaded this (vertex index, texture index) combo, just add it to the // index buffer. indices . push ( vtx_index as _ ) ; continue ; } // This is a new unique vertex (where a vertex is both a position and it's // texture coordinate) so add it to the vertex buffer and the index buffer. let current_vertex = model_vertices [ vert . 0 ] ; let vertex_as_float = [ current_vertex . x as f32 , current_vertex . y as f32 , current_vertex . z as f32 , ] ; let texture_vertices = & obj_set . objects [ 0 ] . tex_vertices ; let tex_vertex = texture_vertices [ vert . 1 . unwrap ( ) ] ; // TODO BACKENDS only flip on coordinate systems that should. let texture_vertex_as_float = [ tex_vertex . u as f32 , 1f32 - tex_vertex . v as f32 ] ; // Ignoring normals, there is no shading in this example. // Keep track of which keys were inserted and add this vertex to the index // buffer. inserted_indices . insert ( index_key , vertices . len ( ) ) ; indices . push ( vertices . len ( ) as _ ) ; // Add to the vertex buffer. vertices . push ( DefaultForwardShaderVertex :: new_with_texture ( & vertex_as_float , & texture_vertex_as_float , ) ) ; } } _ => warn ! ( " " ) , } } } info ! ( " " vertices len ( ) indices len ( ) ) ; ( vertices , Some ( indices ) ) }
For now only use the first object in the obj file.
For now only use the first object in the obj file .
obj_file_path
&str