Browse Source

Implement custom block conversion function

master
NGnius 3 years ago
parent
commit
ff74437b6c
2 changed files with 27 additions and 10 deletions
  1. +1
    -1
      src/convert/mod.rs
  2. +26
    -9
      src/convert/robocraft_3d.rs

+ 1
- 1
src/convert/mod.rs View File

@@ -5,4 +5,4 @@
#[cfg(feature = "robocraft")]
mod robocraft_3d;
#[cfg(feature = "robocraft")]
pub use robocraft_3d::cubes_to_model;
pub use robocraft_3d::{cubes_to_model, cubes_to_model_with_lut};

+ 26
- 9
src/convert/robocraft_3d.rs View File

@@ -1,27 +1,37 @@
use genmesh::{generators::Cube, Quad, MapToVertices, Vertices};
use genmesh::{generators::Cube, Quad, MapToVertices, Vertices, Vertex};
use obj;
use crate::robocraft;

const SCALE: f32 = 0.5;

/// Convert a Robocraft robot to a 3D model in Wavefront OBJ format.
pub fn cubes_to_model(robot: robocraft::Cubes) -> obj::Obj {
let mut positions = Vec::<[f32; 3]>::new();
let mut normals = Vec::<[f32; 3]>::new();
let mut objects = Vec::<obj::Object>::new();
cubes_to_model_with_lut(robot, default_model_lut)
}

/// Convert a Robocraft robot to a 3D model in Wavefront OBJ format using the provided lookup table function.
pub fn cubes_to_model_with_lut<F: FnMut(u32) -> Vec<Quad<Vertex>>>(robot: robocraft::Cubes, mut lut: F) -> obj::Obj {
let mut positions = Vec::<[f32; 3]>::new(); // vertex positions
let mut normals = Vec::<[f32; 3]>::new(); // vertex normals
let mut objects = Vec::<obj::Object>::new(); // blocks
let mut last = 0;
for cube in robot.into_iter() {
// generate simple cube for every block
// TODO rotate blocks
let vertices = lut(cube.id); // Use lookup table to find correct id <-> block translation
positions.extend::<Vec::<[f32; 3]>>(
Cube::new().vertex(|v|
[(v.pos.x * 0.5) + (cube.x as f32), (v.pos.y * 0.5) + (cube.y as f32), (v.pos.z * 0.5) + (cube.z as f32)])
vertices.clone().into_iter().vertex(|v|
[(v.pos.x * SCALE) + (cube.x as f32), (v.pos.y * SCALE) + (cube.y as f32), (v.pos.z * SCALE) + (cube.z as f32)])
.vertices()
.collect()
);
normals.extend::<Vec::<[f32; 3]>>(
Cube::new().vertex(|v|
[(v.normal.x * 0.5) + (cube.x as f32), (v.normal.y * 0.5) + (cube.y as f32), (v.normal.z * 0.5) + (cube.z as f32)])
vertices.clone().into_iter().vertex(|v|
[(v.normal.x * SCALE) + (cube.x as f32), (v.normal.y * SCALE) + (cube.y as f32), (v.normal.z * SCALE) + (cube.z as f32)])
.vertices()
.collect()
);
let polys = Cube::new().vertex(|_| {last+=1; return last-1;})
let polys = vertices.clone().into_iter().vertex(|_| {last+=1; return last-1;})
.map(|Quad{x: v0, y: v1, z: v2, w: v3}|
obj::SimplePolygon(vec![
obj::IndexTuple(v0, Some(0), Some(v0)),
@@ -63,3 +73,10 @@ pub fn cubes_to_model(robot: robocraft::Cubes) -> obj::Obj {
path: std::path::PathBuf::new(),
}
}

pub fn default_model_lut(id: u32) -> Vec<Quad<Vertex>> {
// TODO generate non-cube blocks properly
match id {
_ => Cube::new().collect(),
}
}

Loading…
Cancel
Save