From 69175c08f04fda3af4b7e9b969dd20ce8d280792 Mon Sep 17 00:00:00 2001 From: Elias Stepanik <40958815+eliasstepanik@users.noreply.github.com> Date: Wed, 18 Jun 2025 20:36:17 +0200 Subject: [PATCH] Add OBJ voxelization helper --- client/Cargo.toml | 3 ++ .../environment/systems/voxels/octree.rs | 47 ++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/client/Cargo.toml b/client/Cargo.toml index a373ba7..662f3a9 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -23,4 +23,7 @@ rayon = "1.10.0" bincode = "1.3" bevy_app_compute = "0.16" bytemuck = { version = "1.14", features = ["derive"] } +obj = "0.10" +voxelize-rs = "0.1" +nalgebra = "0.18" diff --git a/client/src/plugins/environment/systems/voxels/octree.rs b/client/src/plugins/environment/systems/voxels/octree.rs index bbaf41d..a010295 100644 --- a/client/src/plugins/environment/systems/voxels/octree.rs +++ b/client/src/plugins/environment/systems/voxels/octree.rs @@ -1,6 +1,6 @@ use crate::plugins::environment::systems::voxels::structure::{ - ChunkKey, DirtyVoxel, OctreeNode, Ray, SparseVoxelOctree, Voxel, AABB, CHUNK_SIZE, - NEIGHBOR_OFFSETS, + AABB, CHUNK_SIZE, ChunkKey, DirtyVoxel, NEIGHBOR_OFFSETS, OctreeNode, Ray, SparseVoxelOctree, + Voxel, }; use bevy::asset::Assets; use bevy::math::{DQuat, DVec3}; @@ -589,4 +589,47 @@ impl SparseVoxelOctree { self.occupied_chunks.insert(key); } } + + /// Load a Wavefront `.obj` file and insert all triangles as voxels. + /// `voxel_size` defines the world-space size of the generated voxels. + pub fn insert_obj_file>( + &mut self, + path: P, + voxel: Voxel, + voxel_size: f32, + ) -> Result<(), Box> { + use obj::Obj; + use voxelize_rs::{Triangle, Vector3, voxelize}; + + let obj: Obj = Obj::load(path)?; + + let mut tris = Vec::new(); + for object in &obj.data.objects { + for group in &object.groups { + for poly in &group.polys { + if poly.0.len() < 3 { + continue; + } + for i in 1..poly.0.len() - 1 { + let v0 = obj.data.position[poly.0[0].0]; + let v1 = obj.data.position[poly.0[i].0]; + let v2 = obj.data.position[poly.0[i + 1].0]; + tris.push(Triangle::new( + Vector3::new(v0[0], v0[1], v0[2]), + Vector3::new(v1[0], v1[1], v1[2]), + Vector3::new(v2[0], v2[1], v2[2]), + )); + } + } + } + } + + let size = Vector3::new(voxel_size, voxel_size, voxel_size); + let voxels = voxelize(&tris, &size); + for p in voxels { + self.insert(Vec3::new(p.x, p.y, p.z), voxel); + } + + Ok(()) + } }