|
|
@@ -1,9 +1,37 @@ |
|
|
|
use genmesh::{generators::Cube, Quad, MapToVertices, Vertices, Vertex}; |
|
|
|
use obj; |
|
|
|
use cgmath::{Quaternion, Euler, Deg, Vector3}; |
|
|
|
use crate::robocraft; |
|
|
|
|
|
|
|
const SCALE: f32 = 0.5; |
|
|
|
|
|
|
|
const ROTATIONS: [Euler<Deg<f32>>; 24] = [ |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 0 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 2 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 4 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 6 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 8 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 10 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 12 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 14 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 16 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 18 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 20 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 22 |
|
|
|
Euler{x: Deg(0.0), y: Deg(0.0), z: Deg(0.0)}, // 23 |
|
|
|
]; |
|
|
|
|
|
|
|
/// Convert a Robocraft robot to a 3D model in Wavefront OBJ format. |
|
|
|
pub fn cubes_to_model(robot: robocraft::Cubes) -> obj::Obj { |
|
|
|
cubes_to_model_with_lut(robot, default_model_lut) |
|
|
@@ -19,15 +47,22 @@ pub fn cubes_to_model_with_lut<F: FnMut(u32) -> Vec<Quad<Vertex>>>(robot: robocr |
|
|
|
// generate simple cube for every block |
|
|
|
// TODO rotate blocks |
|
|
|
let vertices = lut(cube.id); // Use lookup table to find correct id <-> block translation |
|
|
|
let rotation: Quaternion<_> = ROTATIONS[cube.orientation as usize].into(); |
|
|
|
positions.extend::<Vec::<[f32; 3]>>( |
|
|
|
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)]) |
|
|
|
{ |
|
|
|
let rotated = rotation * Vector3{x: v.pos.x * SCALE, y: v.pos.y * SCALE, z: v.pos.z * SCALE}; |
|
|
|
[rotated.x + (cube.x as f32), rotated.y + (cube.y as f32), rotated.z + (cube.z as f32)] |
|
|
|
}) |
|
|
|
.vertices() |
|
|
|
.collect() |
|
|
|
); |
|
|
|
normals.extend::<Vec::<[f32; 3]>>( |
|
|
|
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)]) |
|
|
|
{ |
|
|
|
let rotated = rotation * Vector3{x: v.normal.x * SCALE, y: v.normal.y * SCALE, z: v.normal.z * SCALE}; |
|
|
|
[rotated.x + (cube.x as f32), rotated.y + (cube.y as f32), rotated.z + (cube.z as f32)] |
|
|
|
}) |
|
|
|
.vertices() |
|
|
|
.collect() |
|
|
|
); |
|
|
|