52 lines
1.9 KiB
Rust
52 lines
1.9 KiB
Rust
use std::path::Path;
|
|
use std::sync::Arc;
|
|
use tobj::LoadOptions;
|
|
use crate::{BVH, Color, Dielectric, HittableList, HittableObject, Lambertian, Material, Point3, Vec3};
|
|
use crate::hittable::Hittable;
|
|
use crate::triangle::Triangle;
|
|
|
|
pub fn obj_to_hitable(path: &Path) -> HittableObject {
|
|
let mut lo = LoadOptions::default();
|
|
lo.triangulate = true;
|
|
let (models, materials) = tobj::load_obj(path, &lo)
|
|
.unwrap();
|
|
|
|
let default_mat: Arc<Material> = Arc::new(
|
|
Material::Dielectric(
|
|
Dielectric::new(1.5)
|
|
)
|
|
);
|
|
let mut triangles: HittableList = Vec::with_capacity(models.len());
|
|
for model in models {
|
|
let mesh = model.mesh;
|
|
for f in 0..mesh.indices.len() / 3 {
|
|
let i0 = mesh.indices[3 * f] as usize;
|
|
let i1 = mesh.indices[3 * f + 1] as usize;
|
|
let i2 = mesh.indices[3 * f + 2] as usize;
|
|
let v0 = Point3::new(
|
|
mesh.positions[i0 * 3] as f64,
|
|
mesh.positions[i0 * 3 + 1] as f64,
|
|
mesh.positions[i0 * 3 + 2] as f64);
|
|
let v1 = Point3::new(
|
|
mesh.positions[i1 * 3] as f64,
|
|
mesh.positions[i1 * 3 + 1] as f64,
|
|
mesh.positions[i1 * 3 + 2] as f64);
|
|
let v2 = Point3::new(
|
|
mesh.positions[i2 * 3] as f64,
|
|
mesh.positions[i2 * 3 + 1] as f64,
|
|
mesh.positions[i2 * 3 + 2] as f64);
|
|
let triangle = if mesh.normals.len() <= i0 * 3 + 2 {
|
|
Triangle::without_normal(v0, v1, v2, default_mat.clone())
|
|
} else {
|
|
let normal = Vec3::new(
|
|
mesh.normals[i0 * 3] as f64,
|
|
mesh.normals[i0 * 3 + 1] as f64,
|
|
mesh.normals[i0 * 3 + 2] as f64);
|
|
Triangle::new(v0, v1, v2, normal, default_mat.clone())
|
|
};
|
|
triangles.push(Arc::new(triangle));
|
|
}
|
|
}
|
|
Arc::new(BVH::new(triangles, 0.0, 1.0))
|
|
}
|