Giter Club home page Giter Club logo

tobj's Introduction

tobj – Tiny OBJ Loader

Crate Build Status

Inspired by Syoyo’s excellent tinyobjloader. Aims to be a simple and lightweight option for loading OBJ files.

Just returns two Vecs containing loaded models and materials.

Triangulation

Meshes can be triangulated on the fly or left as-is.

Only polygons that are trivially convertible to triangle fans are supported. Arbitrary polygons may not behave as expected. The best solution would be to convert your mesh to solely consist of triangles in your modeling software.

Optional – Normals, Texture Coordinates and Vertex Colors

It is assumed that all meshes will at least have positions, but normals, texture coordinates and vertex colors are optional.

If no normals, texture coordinates or vertex colors are found, then the corresponding Vecs for the Mesh will be empty.

Flat Data

Values are stored packed as floats in flat Vecs.

For example, the positions member of a Mesh will contain [x, y, z, x, y, z, ...] which you can then use however you like.

Indices

Indices are also loaded and may re-use vertices already existing in the mesh, this data is stored in the indices member.

When a Mesh contains per vertex per face normals or texture coordinates, positions can be duplicated to be per vertex per face too via the single_index flag. This potentially changes the topology (faces may become disconnected even though their vertices still share a position in space).

By default separate indices for normals and texture coordinates are created. This also guarantees that the topology of the Mesh does not change when either of the latter are specified per vertex per face.

Materials

Standard MTL attributes are supported too. Any unrecognized parameters will be stored in a HashMap containing the key-value pairs of the unrecognized parameter and its value.

Features

  • ahash – On by default. Use AHashMap for hashing when reading files and merging vertices. To disable and use the slower HashMap instead, unset default features in Cargo.toml:

    [dependencies.tobj]
    default-features = false
  • merging – Adds support for merging identical vertex positions on disconnected faces during import.

    Warning: this feature uses const generics and thus requires at least a beta toolchain to build.

  • reordering – Adds support for reordering the normal- and texture coordinate indices.

  • async – Adds support for async loading of obj files from a buffer, with an async material loader. Useful in environments that do not support blocking IO (e.g. WebAssembly).

Documentation

Rust docs can be found here.

Installation

Add the crate as a dependency in your Cargo.toml and you’re all set!

Example

The print mesh example (also below) loads an OBJ file from the command line and prints out some information about its faces, vertices, and materials.

fn main() {
    let obj_file = std::env::args()
        .skip(1)
        .next()
        .expect("A .obj file to print is required");

    let (models, materials) =
        tobj::load_obj(
            &obj_file,
            &tobj::LoadOptions::default()
        )
        .expect("Failed to OBJ load file");

    // Note: If you don't mind missing the materials, you can generate a default.
    let materials = materials.expect("Failed to load MTL file");

    println!("Number of models          = {}", models.len());
    println!("Number of materials       = {}", materials.len());

    for (i, m) in models.iter().enumerate() {
        let mesh = &m.mesh;
        println!("");
        println!("model[{}].name             = \'{}\'", i, m.name);
        println!("model[{}].mesh.material_id = {:?}", i, mesh.material_id);

        println!(
            "model[{}].face_count       = {}",
            i,
            mesh.face_arities.len()
        );

        let mut next_face = 0;
        for face in 0..mesh.face_arities.len() {
            let end = next_face + mesh.face_arities[face] as usize;

            let face_indices = &mesh.indices[next_face..end];
            println!(" face[{}].indices          = {:?}", face, face_indices);

            if !mesh.texcoord_indices.is_empty() {
                let texcoord_face_indices = &mesh.texcoord_indices[next_face..end];
                println!(
                    " face[{}].texcoord_indices = {:?}",
                    face, texcoord_face_indices
                );
            }
            if !mesh.normal_indices.is_empty() {
                let normal_face_indices = &mesh.normal_indices[next_face..end];
                println!(
                    " face[{}].normal_indices   = {:?}",
                    face, normal_face_indices
                );
            }

            next_face = end;
        }

        // Normals and texture coordinates are also loaded, but not printed in
        // this example.
        println!(
            "model[{}].positions        = {}",
            i,
            mesh.positions.len() / 3
        );
        assert!(mesh.positions.len() % 3 == 0);

        for vtx in 0..mesh.positions.len() / 3 {
            println!(
                "              position[{}] = ({}, {}, {})",
                vtx,
                mesh.positions[3 * vtx],
                mesh.positions[3 * vtx + 1],
                mesh.positions[3 * vtx + 2]
            );
        }
    }

    for (i, m) in materials.iter().enumerate() {
        println!("material[{}].name = \'{}\'", i, m.name);
        println!(
            "    material.Ka = ({}, {}, {})",
            m.ambient[0], m.ambient[1], m.ambient[2]
        );
        println!(
            "    material.Kd = ({}, {}, {})",
            m.diffuse[0], m.diffuse[1], m.diffuse[2]
        );
        println!(
            "    material.Ks = ({}, {}, {})",
            m.specular[0], m.specular[1], m.specular[2]
        );
        println!("    material.Ns = {}", m.shininess);
        println!("    material.d = {}", m.dissolve);
        println!("    material.map_Ka = {}", m.ambient_texture);
        println!("    material.map_Kd = {}", m.diffuse_texture);
        println!("    material.map_Ks = {}", m.specular_texture);
        println!("    material.map_Ns = {}", m.shininess_texture);
        println!("    material.map_Bump = {}", m.normal_texture);
        println!("    material.map_d = {}", m.dissolve_texture);

        for (k, v) in &m.unknown_param {
            println!("    material.{} = {}", k, v);
        }
    }
}

tobj's People

Contributors

twinklebear avatar virtualritz avatar hwoodiwiss avatar skynoodle avatar alarsyo avatar aleksijuvani avatar azymohliad avatar suficio avatar dylanmckay avatar huonw avatar husenap avatar jeancaspar avatar daseinphaos avatar meiguro avatar ondrowan avatar tkonolige avatar thezalli avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.