Quaternions are now Transmutable.
This implements Transmutable for Quaternions and creates a test and example for this conversion.
This commit is contained in:
parent
aa4bb78f66
commit
1374ff5e4a
89
examples/convert_quaternion.rs
Normal file
89
examples/convert_quaternion.rs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#![feature(convert)]
|
||||||
|
|
||||||
|
extern crate alchemy;
|
||||||
|
extern crate sigils;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
use alchemy::F64_BYTES;
|
||||||
|
use alchemy::{Endianess, Transmutable};
|
||||||
|
use sigils::quaternion::Quaternion;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// The size of 4 f64 Real numbers.
|
||||||
|
/// This would be different if the contained type
|
||||||
|
/// was something different, like an f32.
|
||||||
|
const SIZE_OF_QUATERNION: usize = F64_BYTES * 4;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// This just help pretty up the printing of an array of bytes.
|
||||||
|
fn stringify_array(buffer: &[u8]) -> String
|
||||||
|
{
|
||||||
|
let mut result: String;
|
||||||
|
let mut count: usize;
|
||||||
|
|
||||||
|
// Create a new string that starts with just
|
||||||
|
// the array opening bracket.
|
||||||
|
result = String::new();
|
||||||
|
result.push_str("[");
|
||||||
|
|
||||||
|
// Loop through the buffer keeping track
|
||||||
|
// of our place in it.
|
||||||
|
count = 0usize;
|
||||||
|
for byte in buffer
|
||||||
|
{
|
||||||
|
// Handle priting the last value differently.
|
||||||
|
if count >= buffer.len() - 1
|
||||||
|
{
|
||||||
|
result.push_str(byte.to_string().as_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.push_str(byte.to_string().as_str());
|
||||||
|
result.push_str(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark that we are going to look at
|
||||||
|
// the next byte in the array.
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the array closing bracket and
|
||||||
|
// return the new String.
|
||||||
|
result.push_str("]");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn main()
|
||||||
|
{
|
||||||
|
let quat: Quaternion<f64>;
|
||||||
|
let final_quat: Quaternion<f64>;
|
||||||
|
let endianess: Endianess;
|
||||||
|
let mut buffer: [u8; SIZE_OF_QUATERNION];
|
||||||
|
|
||||||
|
// Initialize the variables.
|
||||||
|
quat = Quaternion::<f64>::from_values(6.29f64, 1.9f64, 8.5f64, 7.11f64);
|
||||||
|
buffer = [0u8; SIZE_OF_QUATERNION];
|
||||||
|
endianess = Endianess::PLATFORM;
|
||||||
|
|
||||||
|
println!("Transmuting a Quaternion:");
|
||||||
|
|
||||||
|
println!("Converting the value [{1}, <{2}, {3}, {4}>] {0}",
|
||||||
|
"into and out of an array of bytes.",
|
||||||
|
quat.scalar, quat.vector.x, quat.vector.y, quat.vector.z);
|
||||||
|
println!("Buffer starts as: {}", stringify_array(&buffer));
|
||||||
|
|
||||||
|
// Convert the Vector2 into an array of bytes.
|
||||||
|
quat.to_bytes(&mut buffer, endianess);
|
||||||
|
|
||||||
|
println!("Buffer contains: {}", stringify_array(&buffer));
|
||||||
|
|
||||||
|
// Convert the array of bytes into a Vector2.
|
||||||
|
final_quat = Quaternion::from_bytes(&buffer, endianess);
|
||||||
|
println!("The buffer converts back to: [{}, <{}, {}, {}>]",
|
||||||
|
final_quat.scalar, final_quat.vector.x,
|
||||||
|
final_quat.vector.y, final_quat.vector.z);
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
use sigils::{Zero, Number};
|
use sigils::{Zero, Number, Real};
|
||||||
use sigils::vector::{Vector, Vector2, Vector3, Vector4};
|
use sigils::vector::{Vector, Vector2, Vector3, Vector4};
|
||||||
|
use sigils::quaternion::Quaternion;
|
||||||
|
|
||||||
use ::byte_sized::ByteSized;
|
use ::byte_sized::ByteSized;
|
||||||
use ::converter::Converter;
|
use ::converter::Converter;
|
||||||
@ -502,3 +503,49 @@ impl<T> Transmutable for Vector4<T> where T: Number + ByteSized + Transmutable
|
|||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Transmutable for Quaternion<T>
|
||||||
|
where T: Real + ByteSized + Transmutable
|
||||||
|
{
|
||||||
|
fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess)
|
||||||
|
{
|
||||||
|
let byte_size: usize;
|
||||||
|
let num_bytes: usize;
|
||||||
|
|
||||||
|
// Determine the number of bytes requires to
|
||||||
|
// represent a Quaternion.
|
||||||
|
byte_size = T::get_byte_size();
|
||||||
|
num_bytes = byte_size * 4usize;
|
||||||
|
|
||||||
|
// Make sure that there is enough space to store
|
||||||
|
// the bytes from this type.
|
||||||
|
assert!(buffer.len() >= num_bytes);
|
||||||
|
|
||||||
|
// Convert this to bytes and add it to the buffer.
|
||||||
|
self.scalar.to_bytes(&mut buffer[0..byte_size], endianess);
|
||||||
|
self.vector.to_bytes(&mut buffer[byte_size..num_bytes], endianess);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_bytes(buffer: &[u8], endianess: Endianess) -> Quaternion<T>
|
||||||
|
{
|
||||||
|
let byte_size: usize;
|
||||||
|
let num_bytes: usize;
|
||||||
|
let mut quat: Quaternion<T>;
|
||||||
|
|
||||||
|
// Determine the number of bytes requires to
|
||||||
|
// represent a Quaternion.
|
||||||
|
quat = Quaternion::<T>::zero();
|
||||||
|
byte_size = T::get_byte_size();
|
||||||
|
num_bytes = byte_size * 4usize;
|
||||||
|
|
||||||
|
// Make sure that there is enough data to read
|
||||||
|
// the bytes for this type.
|
||||||
|
assert!(buffer.len() >= num_bytes);
|
||||||
|
|
||||||
|
// Convert the given bytes to this type and return it.
|
||||||
|
quat.scalar = T::from_bytes(&buffer[0..byte_size], endianess);
|
||||||
|
quat.vector =
|
||||||
|
Vector3::<T>::from_bytes(&buffer[byte_size..num_bytes], endianess);
|
||||||
|
quat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,9 +5,10 @@ extern crate sigils;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
macro_rules! transmutation_test
|
macro_rules! transmutation_vector_test
|
||||||
{
|
{
|
||||||
($modName: ident, $varType: ident, $numBytes: expr, [$($var: ident)*]) =>
|
($modName: ident, $varType: ident, $dataType:ty,
|
||||||
|
$numBytes: expr, [$($var: ident)*]) =>
|
||||||
{
|
{
|
||||||
mod $modName
|
mod $modName
|
||||||
{
|
{
|
||||||
@ -22,16 +23,16 @@ macro_rules! transmutation_test
|
|||||||
#[test]
|
#[test]
|
||||||
pub fn transmutation()
|
pub fn transmutation()
|
||||||
{
|
{
|
||||||
let mut vec: $varType<u64>;
|
let mut vec: $varType<$dataType>;
|
||||||
let final_vec: $varType<u64>;
|
let final_vec: $varType<$dataType>;
|
||||||
let endianess: Endianess;
|
let endianess: Endianess;
|
||||||
let mut rng: ThreadRng;
|
let mut rng: ThreadRng;
|
||||||
let mut buffer: [u8; $numBytes];
|
let mut buffer: [u8; $numBytes];
|
||||||
|
|
||||||
// Initialize the variables.
|
// Initialize the variables.
|
||||||
rng = thread_rng();
|
rng = thread_rng();
|
||||||
vec = $varType::<u64>::zero();
|
vec = $varType::<$dataType>::zero();
|
||||||
$(vec.$var = rng.next_u64();)*
|
$(vec.$var = rng.gen();)*
|
||||||
buffer = [0u8; $numBytes];
|
buffer = [0u8; $numBytes];
|
||||||
endianess = Endianess::PLATFORM;
|
endianess = Endianess::PLATFORM;
|
||||||
|
|
||||||
@ -45,6 +46,47 @@ macro_rules! transmutation_test
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
transmutation_test!(vec2, Vector2, 16, [x y]);
|
transmutation_vector_test!(vec2, Vector2, u64, 16, [x y]);
|
||||||
transmutation_test!(vec3, Vector3, 24, [x y z]);
|
transmutation_vector_test!(vec3, Vector3, u32, 12, [x y z]);
|
||||||
transmutation_test!(vec4, Vector4, 32, [x y z w]);
|
transmutation_vector_test!(vec4, Vector4, u16, 8, [x y z w]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mod quat
|
||||||
|
{
|
||||||
|
use rand::{thread_rng, Rng, ThreadRng};
|
||||||
|
|
||||||
|
use alchemy::{Endianess, Transmutable};
|
||||||
|
use sigils::Zero;
|
||||||
|
use sigils::quaternion::Quaternion;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn transmutation()
|
||||||
|
{
|
||||||
|
let mut quat: Quaternion<f64>;
|
||||||
|
let final_quat: Quaternion<f64>;
|
||||||
|
let endianess: Endianess;
|
||||||
|
let mut rng: ThreadRng;
|
||||||
|
let mut buffer: [u8; 32];
|
||||||
|
|
||||||
|
// Initialize the variables.
|
||||||
|
rng = thread_rng();
|
||||||
|
quat = Quaternion::<f64>::zero();
|
||||||
|
quat.scalar = rng.gen();
|
||||||
|
quat.vector.x = rng.gen();
|
||||||
|
quat.vector.y = rng.gen();
|
||||||
|
quat.vector.z = rng.gen();
|
||||||
|
buffer = [0u8; 32];
|
||||||
|
endianess = Endianess::PLATFORM;
|
||||||
|
|
||||||
|
quat.to_bytes(&mut buffer, endianess);
|
||||||
|
final_quat = Quaternion::from_bytes(&buffer, endianess);
|
||||||
|
|
||||||
|
assert_eq!(quat.scalar, final_quat.scalar);
|
||||||
|
assert_eq!(quat.vector.x, final_quat.vector.x);
|
||||||
|
assert_eq!(quat.vector.y, final_quat.vector.y);
|
||||||
|
assert_eq!(quat.vector.z, final_quat.vector.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user