From 756948bdf75b558e220ff307296a0a23b28a3f00 Mon Sep 17 00:00:00 2001 From: NGnius Date: Mon, 25 Oct 2021 17:34:05 -0400 Subject: [PATCH] Partially implement block conversion rotation support --- Cargo.toml | 3 ++- src/convert/robocraft_3d.rs | 39 +++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 332988f..508c5f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ libfj_parsable_macro_derive = {version = "0.5.3", optional = true} #libfj_parsable_macro_derive = {path = "./parsable_macro_derive", optional = true} obj = {version = "^0.10", optional = true} genmesh = {version = "^0.6", optional = true} +cgmath = {version = "^0.18", optional = true} [dev-dependencies] tokio = { version = "1.4.0", features = ["macros"]} @@ -41,4 +42,4 @@ simple = ["ureq"] robocraft = ["reqwest", "ureq"] cardlife = ["reqwest"] techblox = ["chrono", "highhash", "half", "libfj_parsable_macro_derive"] -convert = ["obj", "genmesh"] +convert = ["obj", "genmesh", "cgmath"] diff --git a/src/convert/robocraft_3d.rs b/src/convert/robocraft_3d.rs index 439970e..3dd2c70 100644 --- a/src/convert/robocraft_3d.rs +++ b/src/convert/robocraft_3d.rs @@ -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>; 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 Vec>>(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::>( 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::>( 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() );