1 module math.linear._qv; 2 3 import core.internal.traits : Unconst; 4 ////import std.traits : Unconst; 5 import std.traits; 6 public import math.linear.quaternion; 7 public import math.linear.vector; 8 9 auto opBinaryImpl(string op:"*", T,U)(const Quat!T at, const Vec!(U,3) b) 10 if (isNumeric!T && isNumeric!U) 11 { 12 alias NT = Unconst!(typeof(rvalueOf!T*rvalueOf!U)); 13 static if (isFloatingPoint!T && !isFloatingPoint!U) 14 auto a = at.castType!real; 15 else 16 alias a = at; 17 18 auto ww = a.w^^2; 19 auto w2 = a.w * 2; 20 auto wx2 = w2 * a.x; 21 auto wy2 = w2 * a.y; 22 auto wz2 = w2 * a.z; 23 auto xx = a.x^^2; 24 auto x2 = a.x * 2; 25 auto xy2 = x2 * a.y; 26 auto xz2 = x2 * a.z; 27 auto yy = a.y^^2; 28 auto yz2 = a.y * a.z * 2; 29 auto zz = a.z * a.z; 30 31 return Vec!(NT,3) ( ww * b.x + wy2 * b.z - wz2 * b.y + xx * b.x + 32 xy2 * b.y + xz2 * b.z - zz * b.x - yy * b.x 33 , xy2 * b.x + yy * b.y + yz2 * b.z + wz2 * b.x - 34 zz * b.y + ww * b.y - wx2 * b.z - xx * b.y 35 , xz2 * b.x + yz2 * b.y + zz * b.z - wy2 * b.x - 36 yy * b.z + wx2 * b.y - xx * b.z + ww * b.z 37 ).castType!U; 38 } 39 auto opBinaryImpl(string op:"*", T,U)(const Vec!(T,3) a, const Quat!U b) 40 if (isNumeric!T && isNumeric!U) 41 { 42 return b*a; 43 } 44 45 46 void opOpAssignImpl(string op:"*", T,U)(ref Vec!(T,3) a, const Quat!U b) 47 if (isNumeric!T && isNumeric!U) 48 { 49 T ww = b.w^^2; 50 T w2 = b.w * 2; 51 T wx2 = w2 * b.x; 52 T wy2 = w2 * b.y; 53 T wz2 = w2 * b.z; 54 T xx = b.x^^2; 55 T x2 = b.x * 2; 56 T xy2 = x2 * b.y; 57 T xz2 = x2 * b.z; 58 T yy = b.y^^2; 59 T yz2 = b.y * b.z * 2; 60 T zz = b.z * b.z; 61 62 a.x = ww * a.x + wy2 * a.z - wz2 * a.y + xx * a.x + 63 xy2 * a.y + xz2 * a.z - zz * a.x - yy * a.x ; 64 a.y = xy2 * a.x + yy * a.y + yz2 * a.z + wz2 * a.x - 65 zz * a.y + ww * a.y - wx2 * a.z - xx * a.y ; 66 a.z = xz2 * a.x + yz2 * a.y + zz * a.z - wy2 * a.x - 67 yy * a.z + wx2 * a.y - xx * a.z + ww * a.z ; 68 } 69 70 71 unittest { 72 void testValues(A,B)(A a1, A a2, A a3, A a4, B b1, B b2, B b3) { 73 { 74 Quat!A a = [a1,a2,a3,a4]; 75 Vec!(B,3) b = [b1,b2,b3]; 76 static assert(is(typeof(a*b) == Vec!(typeof(a1+b1),3))); 77 } 78 { 79 const Quat!A a = [a1,a2,a3,a4]; 80 const Vec!(B,3) b = [b1,b2,b3]; 81 static assert(is(typeof(a*b) == Vec!(typeof(a1+b1),3))); 82 } 83 { 84 Quat!A a = [a1,a2,a3,a4]; 85 const Vec!(B,3) b = [b1,b2,b3]; 86 static assert(is(typeof(a*b) == Vec!(typeof(a1+b1),3))); 87 } 88 { 89 const Quat!A a = [a1,a2,a3,a4]; 90 Vec!(B,3) b = [b1,b2,b3]; 91 static assert(is(typeof(a*b) == Vec!(typeof(a1+b1),3))); 92 } 93 } 94 testValues!(int,int)(1,2,3,4,2,3,4); 95 testValues!(float,float)(1.5,2.5,3,4,2.5,3,4.5); 96 testValues!(int,float)(1,2,3,4,2.5,3,4.5); 97 testValues!(float,double)(1.5,2.5,3,4,2.5,3,4.5); 98 } 99