<commit_before>use cast::transmute;
use cmp::Eq;
use num::from_int;
use ptr::to_unsafe_ptr;
use vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;

use funs::exp::*;
use funs::trig::*;
use funs::common::*;
use math::*;
use matrix::{Mat3, Mat4};
use ncast::*;
use vector::Vec3;


// These quaternion type aliases are not actually specified in the GLSL spec
// but they follow the same nomenclature

pub type quat4  = Quat<f32>;         /// a single-precision floating-point quaternion
pub type dquat4 = Quat<f64>;         /// a double-precision floating-point quaternion

//
//  Quaternion
//
pub trait Quaternion<T> {
    pure fn dim() -> uint;
    
    pure fn mul_t(value: T) -> self;
    pure fn div_t(value: T) -> self;
    
    // pure fn mul_v(other: &Vec3) -> Vec3;
    
    pure fn add_q(other: &self) -> self;
    pure fn sub_q(other: &self) -> self;
    pure fn mul_q(other: &self) -> self;
    
    pure fn dot(other: &self) -> T;
    
    pure fn conjugate() -> self;
    pure fn inverse() -> self;
    pure fn length2() -> T;
    pure fn length() -> T;
    pure fn normalize() -> self;
    
    pure fn nlerp(other: &self, amount: T) -> self;
    pure fn slerp(other: &self, amount: T) -> self;
    
    pure fn to_Mat3() -> Mat3<T>;
    pure fn to_Mat4() -> Mat4<T>;
}

pub trait ToQuat<T> {
    pure fn to_Quat() -> Quat<T>;
}






pub struct Quat<T> { w: T, x: T, y: T, z: T }

pub mod Quat {
    
    #[inline(always)]
    pub pure fn new<T>(w: T, x: T, y: T, z: T) -> Quat<T> {
        Quat { w: move w, x: move x, y: move y, z: move z }
    }
    
    #[inline(always)]
    pub pure fn from_sv<T:Copy>(s: T, v: Vec3<T>) -> Quat<T> {
        Quat::new(s, v.x, v.y, v.z)
    }
    
    #[inline(always)]
    pub pure fn zero<T:Copy NumCast>() -> Quat<T> {
        let _0 = cast(0);
        Quat::new(_0, _0, _0, _0)
    }
    
    #[inline(always)]
    pub pure fn identity<T:Copy NumCast>() -> Quat<T> {
        let _0 = cast(0);
        Quat::new(cast(1), _0, _0, _0)
    }
}

pub impl<T:Copy Num NumCast Trig Exp Extent Ord FuzzyEq> Quat<T>: Quaternion<T> {
    #[inline(always)]
    pure fn dim() -> uint { 4 }
    
    #[inline(always)]
    pure fn mul_t(value: T) -> Quat<T> {
        Quat::new(self[0] * value,
                  self[1] * value,
                  self[2] * value,
                  self[3] * value)
    }
    
    #[inline(always)]
    pure fn div_t(value: T) -> Quat<T> {
        Quat::new(self[0] / value,
                  self[1] / value,
                  self[2] / value,
                  self[3] / value)
    }
    
    #[inline(always)]
    pure fn add_q(other: &Quat<T>) -> Quat<T> {
        Quat::new(self[0] + other[0],
                  self[1] + other[1],
                  self[2] + other[2],
                  self[3] + other[3])
    }
    
    #[inline(always)]
    pure fn sub_q(other: &Quat<T>) -> Quat<T> {<commit_msg>Add mul_v method and from_axis_angle function (thanks Dzmitry)<commit_after>use cast::transmute;
use cmp::Eq;
use num::from_int;
use ptr::to_unsafe_ptr;
use vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;

use funs::exp::*;
use funs::trig::*;
use funs::common::*;
use math::*;
use matrix::{Mat3, Mat4};
use ncast::*;
use vector::Vec3;


// These quaternion type aliases are not actually specified in the GLSL spec
// but they follow the same nomenclature

pub type quat4  = Quat<f32>;         /// a single-precision floating-point quaternion
pub type dquat4 = Quat<f64>;         /// a double-precision floating-point quaternion

//
//  Quaternion
//
pub trait Quaternion<T> {
    pure fn dim() -> uint;
    
    pure fn mul_t(value: T) -> self;
    pure fn div_t(value: T) -> self;
    
    pure fn mul_v(vec: &Vec3<T>) -> Vec3<T>;
    
    pure fn add_q(other: &self) -> self;
    pure fn sub_q(other: &self) -> self;
    pure fn mul_q(other: &self) -> self;
    
    pure fn dot(other: &self) -> T;
    
    pure fn conjugate() -> self;
    pure fn inverse() -> self;
    pure fn length2() -> T;
    pure fn length() -> T;
    pure fn normalize() -> self;
    
    pure fn nlerp(other: &self, amount: T) -> self;
    pure fn slerp(other: &self, amount: T) -> self;
    
    pure fn to_Mat3() -> Mat3<T>;
    pure fn to_Mat4() -> Mat4<T>;
}

pub trait ToQuat<T> {
    pure fn to_Quat() -> Quat<T>;
}






pub struct Quat<T> { w: T, x: T, y: T, z: T }

pub mod Quat {
    #[inline(always)]
    pub pure fn new<T>(w: T, x: T, y: T, z: T) -> Quat<T> {
        Quat { w: move w, x: move x, y: move y, z: move z }
    }
    
    #[inline(always)]
    pub pure fn from_sv<T:Copy>(s: T, v: Vec3<T>) -> Quat<T> {
        Quat::new(s, v.x, v.y, v.z)
    }

    #[inline(always)]
    pub pure fn from_axis_angle<T:Copy Num NumCast Trig AngleConv>(axis: Vec3<T>, theta: T) -> Quat<T> {
        let half = radians(&theta) / cast(2);
        from_sv(cos(&half), axis.mul_t(sin(&half)))
    }
    
    #[inline(always)]
    pub pure fn zero<T:Copy NumCast>() -> Quat<T> {
        let _0 = cast(0);
        Quat::new(_0, _0, _0, _0)
    }
    
    #[inline(always)]
    pub pure fn identity<T:Copy NumCast>() -> Quat<T> {
        let _0 = cast(0);
        Quat::new(cast(1), _0, _0, _0)
    }
}

pub impl<T:Copy Num NumCast Trig Exp Extent Ord FuzzyEq> Quat<T>: Quaternion<T> {
    #[inline(always)]
    pure fn dim() -> uint { 4 }
    
    #[inline(always)]
    pure fn mul_t(value: T) -> Quat<T> {
        Quat::new(self[0] * value,
                  self[1] * value,
                  self[2] * value,
                  self[3] * value)
    }
    
    #[inline(always)]
    pure fn div_t(value: T) -> Quat<T> {
        Quat::new(self[0] / value,
                  self[1] / value,
                  self[2] / value,
                  self[3] / value)
    }

    #[inline(always)]
    pure fn mul_v(vec: &Vec3<T>) -> Vec3<T>  {
        let base = Vec3{ x:self.x, y:self.y, z:self.z };
        let tmp = base.cross(vec).add_v(&vec.mul_t(self.w));
        base.cross(&tmp).mul_t(cast(2)).add_v(vec)
    }
    
    #[inline(always)]
    pure fn add_q(other: &Quat<T>) -> Quat<T> {
        Quat::new(self[0] + other[0],
                  self[1] + other[1],
                  self[2] + other[2],
                  self[3] + other[3])
    }
    
    #[inline(always)]
    pure fn sub_q(other: &Quat<T>) -> Quat<T> {
{'fraction_non_alphanumeric': 0.17229837424290723, 'fraction_numerical': 0.015620019126554032, 'mean_word_length': 2.107974244675582, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 118, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4073469', 'n_tokens_mistral': 2471, 'n_tokens_neox': 2423, 'n_words': 640}