3 * Copyright (c) 2007-2010 SlimDX Group
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
\r
6 * of this software and associated documentation files (the "Software"), to deal
\r
7 * in the Software without restriction, including without limitation the rights
\r
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
9 * copies of the Software, and to permit persons to whom the Software is
\r
10 * furnished to do so, subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in
\r
13 * all copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
27 #include "Quaternion.h"
\r
28 #include "Vector3.h"
\r
30 using namespace System;
\r
31 using namespace System::Globalization;
\r
35 Quaternion::Quaternion(float x, float y, float z, float w)
\r
43 Quaternion::Quaternion( Vector3 value, float w )
\r
51 Quaternion Quaternion::Identity::get()
\r
61 bool Quaternion::IsIdentity::get()
\r
63 if( X != 0.0f || Y != 0.0f || Z != 0.0f )
\r
69 Vector3 Quaternion::Axis::get()
\r
71 pin_ptr<Quaternion> pinThis = this;
\r
75 D3DXQuaternionToAxisAngle( (D3DXQUATERNION*) pinThis, (D3DXVECTOR3*) &axis, &angle );
\r
79 float Quaternion::Angle::get()
\r
81 pin_ptr<Quaternion> pinThis = this;
\r
85 D3DXQuaternionToAxisAngle( (D3DXQUATERNION*) pinThis, (D3DXVECTOR3*) &axis, &angle );
\r
89 float Quaternion::Length()
\r
91 return static_cast<float>( Math::Sqrt( (X * X) + (Y * Y) + (Z * Z) + (W * W) ) );
\r
94 float Quaternion::LengthSquared()
\r
96 return (X * X) + (Y * Y) + (Z * Z) + (W * W);
\r
99 void Quaternion::Normalize()
\r
101 float length = 1.0f / Length();
\r
108 void Quaternion::Conjugate()
\r
115 void Quaternion::Invert()
\r
117 float lengthSq = 1.0f / ( (X * X) + (Y * Y) + (Z * Z) + (W * W) );
\r
124 Quaternion Quaternion::Add( Quaternion left, Quaternion right )
\r
127 result.X = left.X + right.X;
\r
128 result.Y = left.Y + right.Y;
\r
129 result.Z = left.Z + right.Z;
\r
130 result.W = left.W + right.W;
\r
134 void Quaternion::Add( Quaternion% left, Quaternion% right, [Out] Quaternion% result )
\r
137 r.X = left.X + right.X;
\r
138 r.Y = left.Y + right.Y;
\r
139 r.Z = left.Z + right.Z;
\r
140 r.W = left.W + right.W;
\r
145 Quaternion Quaternion::Barycentric( Quaternion q1, Quaternion q2, Quaternion q3, float f, float g )
\r
149 D3DXQuaternionBaryCentric( (D3DXQUATERNION*) &result, (D3DXQUATERNION*) &q1,
\r
150 (D3DXQUATERNION*) &q2, (D3DXQUATERNION*) &q3, f, g );
\r
155 void Quaternion::Barycentric( Quaternion% q1, Quaternion% q2, Quaternion% q3, float f, float g, [Out] Quaternion% result )
\r
157 pin_ptr<Quaternion> pin1 = &q1;
\r
158 pin_ptr<Quaternion> pin2 = &q2;
\r
159 pin_ptr<Quaternion> pin3 = &q3;
\r
160 pin_ptr<Quaternion> pinResult = &result;
\r
162 D3DXQuaternionBaryCentric( (D3DXQUATERNION*) pinResult, (D3DXQUATERNION*) pin1,
\r
163 (D3DXQUATERNION*) pin2, (D3DXQUATERNION*) pin3, f, g );
\r
166 Quaternion Quaternion::Conjugate( Quaternion quat )
\r
169 result.X = -quat.X;
\r
170 result.Y = -quat.Y;
\r
171 result.Z = -quat.Z;
\r
176 void Quaternion::Conjugate( Quaternion% quat, [Out] Quaternion% result )
\r
178 result.X = -quat.X;
\r
179 result.Y = -quat.Y;
\r
180 result.Z = -quat.Z;
\r
184 Quaternion Quaternion::Divide( Quaternion left, Quaternion right )
\r
187 result.X = left.X / right.X;
\r
188 result.Y = left.Y / right.Y;
\r
189 result.Z = left.Z / right.Z;
\r
190 result.W = left.W / right.W;
\r
194 void Quaternion::Divide( Quaternion% left, Quaternion% right, [Out] Quaternion% result )
\r
196 result.X = left.X / right.X;
\r
197 result.Y = left.Y / right.Y;
\r
198 result.Z = left.Z / right.Z;
\r
199 result.W = left.W / right.W;
\r
202 float Quaternion::Dot( Quaternion left, Quaternion right )
\r
204 return (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z) + (left.W * right.W);
\r
207 Quaternion Quaternion::Exponential( Quaternion quat )
\r
210 D3DXQuaternionExp( (D3DXQUATERNION*) &result, (D3DXQUATERNION*) &quat );
\r
214 void Quaternion::Exponential( Quaternion% quat, [Out] Quaternion% result )
\r
216 pin_ptr<Quaternion> pinQuat = &quat;
\r
217 pin_ptr<Quaternion> pinResult = &result;
\r
219 D3DXQuaternionExp( (D3DXQUATERNION*) pinResult, (D3DXQUATERNION*) pinQuat );
\r
222 Quaternion Quaternion::Invert( Quaternion quaternion )
\r
225 float lengthSq = 1.0f / ( (quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y) + (quaternion.Z * quaternion.Z) + (quaternion.W * quaternion.W) );
\r
227 result.X = -quaternion.X * lengthSq;
\r
228 result.Y = -quaternion.Y * lengthSq;
\r
229 result.Z = -quaternion.Z * lengthSq;
\r
230 result.W = quaternion.W * lengthSq;
\r
235 void Quaternion::Invert( Quaternion% quaternion, [Out] Quaternion% result )
\r
237 float lengthSq = 1.0f / ( (quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y) + (quaternion.Z * quaternion.Z) + (quaternion.W * quaternion.W) );
\r
239 result.X = -quaternion.X * lengthSq;
\r
240 result.Y = -quaternion.Y * lengthSq;
\r
241 result.Z = -quaternion.Z * lengthSq;
\r
242 result.W = quaternion.W * lengthSq;
\r
245 Quaternion Quaternion::Lerp( Quaternion left, Quaternion right, float amount )
\r
248 float inverse = 1.0f - amount;
\r
249 float dot = (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z) + (left.W * right.W);
\r
253 result.X = (inverse * left.X) + (amount * right.X);
\r
254 result.Y = (inverse * left.Y) + (amount * right.Y);
\r
255 result.Z = (inverse * left.Z) + (amount * right.Z);
\r
256 result.W = (inverse * left.W) + (amount * right.W);
\r
260 result.X = (inverse * left.X) - (amount * right.X);
\r
261 result.Y = (inverse * left.Y) - (amount * right.Y);
\r
262 result.Z = (inverse * left.Z) - (amount * right.Z);
\r
263 result.W = (inverse * left.W) - (amount * right.W);
\r
266 float invLength = 1.0f / result.Length();
\r
268 result.X *= invLength;
\r
269 result.Y *= invLength;
\r
270 result.Z *= invLength;
\r
271 result.W *= invLength;
\r
276 void Quaternion::Lerp( Quaternion% left, Quaternion% right, float amount, [Out] Quaternion% result )
\r
278 float inverse = 1.0f - amount;
\r
279 float dot = (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z) + (left.W * right.W);
\r
283 result.X = (inverse * left.X) + (amount * right.X);
\r
284 result.Y = (inverse * left.Y) + (amount * right.Y);
\r
285 result.Z = (inverse * left.Z) + (amount * right.Z);
\r
286 result.W = (inverse * left.W) + (amount * right.W);
\r
290 result.X = (inverse * left.X) - (amount * right.X);
\r
291 result.Y = (inverse * left.Y) - (amount * right.Y);
\r
292 result.Z = (inverse * left.Z) - (amount * right.Z);
\r
293 result.W = (inverse * left.W) - (amount * right.W);
\r
296 float invLength = 1.0f / result.Length();
\r
298 result.X *= invLength;
\r
299 result.Y *= invLength;
\r
300 result.Z *= invLength;
\r
301 result.W *= invLength;
\r
304 Quaternion Quaternion::Logarithm( Quaternion quat )
\r
307 D3DXQuaternionLn( (D3DXQUATERNION*) &result, (D3DXQUATERNION*) &quat );
\r
311 void Quaternion::Logarithm( Quaternion% quat, [Out] Quaternion% result )
\r
313 pin_ptr<Quaternion> pinQuat = &quat;
\r
314 pin_ptr<Quaternion> pinResult = &result;
\r
316 D3DXQuaternionLn( (D3DXQUATERNION*) pinResult, (D3DXQUATERNION*) pinQuat );
\r
319 Quaternion Quaternion::Multiply( Quaternion left, Quaternion right )
\r
321 Quaternion quaternion;
\r
326 float rx = right.X;
\r
327 float ry = right.Y;
\r
328 float rz = right.Z;
\r
329 float rw = right.W;
\r
331 quaternion.X = (rx * lw + lx * rw + ry * lz) - (rz * ly);
\r
332 quaternion.Y = (ry * lw + ly * rw + rz * lx) - (rx * lz);
\r
333 quaternion.Z = (rz * lw + lz * rw + rx * ly) - (ry * lx);
\r
334 quaternion.W = (rw * lw) - (rx * lx + ry * ly + rz * lz);
\r
339 void Quaternion::Multiply( Quaternion% left, Quaternion% right, [Out] Quaternion% result )
\r
345 float rx = right.X;
\r
346 float ry = right.Y;
\r
347 float rz = right.Z;
\r
348 float rw = right.W;
\r
350 result.X = (rx * lw + lx * rw + ry * lz) - (rz * ly);
\r
351 result.Y = (ry * lw + ly * rw + rz * lx) - (rx * lz);
\r
352 result.Z = (rz * lw + lz * rw + rx * ly) - (ry * lx);
\r
353 result.W = (rw * lw) - (rx * lx + ry * ly + rz * lz);
\r
356 Quaternion Quaternion::Multiply( Quaternion quaternion, float scale )
\r
359 result.X = quaternion.X * scale;
\r
360 result.Y = quaternion.Y * scale;
\r
361 result.Z = quaternion.Z * scale;
\r
362 result.W = quaternion.W * scale;
\r
366 void Quaternion::Multiply( Quaternion% quaternion, float scale, [Out] Quaternion% result )
\r
368 result.X = quaternion.X * scale;
\r
369 result.Y = quaternion.Y * scale;
\r
370 result.Z = quaternion.Z * scale;
\r
371 result.W = quaternion.W * scale;
\r
374 Quaternion Quaternion::Negate( Quaternion quat )
\r
377 result.X = -quat.X;
\r
378 result.Y = -quat.Y;
\r
379 result.Z = -quat.Z;
\r
380 result.W = -quat.W;
\r
384 void Quaternion::Negate( Quaternion% quat, [Out] Quaternion% result )
\r
386 result.X = -quat.X;
\r
387 result.Y = -quat.Y;
\r
388 result.Z = -quat.Z;
\r
389 result.W = -quat.W;
\r
392 Quaternion Quaternion::Normalize( Quaternion quat )
\r
398 void Quaternion::Normalize( Quaternion% quat, [Out] Quaternion% result )
\r
400 float length = 1.0f / quat.Length();
\r
401 result.X = quat.X * length;
\r
402 result.Y = quat.Y * length;
\r
403 result.Z = quat.Z * length;
\r
404 result.W = quat.W * length;
\r
407 Quaternion Quaternion::RotationAxis( Vector3 axis, float angle )
\r
411 Vector3::Normalize( axis, axis );
\r
413 float half = angle * 0.5f;
\r
414 float sin = static_cast<float>( Math::Sin( static_cast<double>( half ) ) );
\r
415 float cos = static_cast<float>( Math::Cos( static_cast<double>( half ) ) );
\r
417 result.X = axis.X * sin;
\r
418 result.Y = axis.Y * sin;
\r
419 result.Z = axis.Z * sin;
\r
425 void Quaternion::RotationAxis( Vector3% axis, float angle, [Out] Quaternion% result )
\r
427 Vector3::Normalize( axis, axis );
\r
429 float half = angle * 0.5f;
\r
430 float sin = static_cast<float>( Math::Sin( static_cast<double>( half ) ) );
\r
431 float cos = static_cast<float>( Math::Cos( static_cast<double>( half ) ) );
\r
433 result.X = axis.X * sin;
\r
434 result.Y = axis.Y * sin;
\r
435 result.Z = axis.Z * sin;
\r
439 Quaternion Quaternion::RotationMatrix( Matrix matrix )
\r
442 float scale = matrix.M11 + matrix.M22 + matrix.M33;
\r
446 float sqrt = static_cast<float>( Math::Sqrt( static_cast<double>(scale + 1.0f) ) );
\r
448 result.W = sqrt * 0.5f;
\r
449 sqrt = 0.5f / sqrt;
\r
451 result.X = (matrix.M23 - matrix.M32) * sqrt;
\r
452 result.Y = (matrix.M31 - matrix.M13) * sqrt;
\r
453 result.Z = (matrix.M12 - matrix.M21) * sqrt;
\r
458 if( (matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33) )
\r
460 float sqrt = static_cast<float>( Math::Sqrt( static_cast<double>(1.0f + matrix.M11 - matrix.M22 - matrix.M33) ) );
\r
461 float half = 0.5f / sqrt;
\r
463 result.X = 0.5f * sqrt;
\r
464 result.Y = (matrix.M12 + matrix.M21) * half;
\r
465 result.Z = (matrix.M13 + matrix.M31) * half;
\r
466 result.W = (matrix.M23 - matrix.M32) * half;
\r
471 if( matrix.M22 > matrix.M33 )
\r
473 float sqrt = static_cast<float>( Math::Sqrt( static_cast<double>(1.0f + matrix.M22 - matrix.M11 - matrix.M33) ) );
\r
474 float half = 0.5f / sqrt;
\r
476 result.X = (matrix.M21 + matrix.M12) * half;
\r
477 result.Y = 0.5f * sqrt;
\r
478 result.Z = (matrix.M32 + matrix.M23) * half;
\r
479 result.W = (matrix.M31 - matrix.M13) * half;
\r
484 float sqrt = static_cast<float>( Math::Sqrt( static_cast<double>(1.0f + matrix.M33 - matrix.M11 - matrix.M22) ) );
\r
485 float half = 0.5f / sqrt;
\r
487 result.X = (matrix.M31 + matrix.M13) * half;
\r
488 result.Y = (matrix.M32 + matrix.M23) * half;
\r
489 result.Z = 0.5f * sqrt;
\r
490 result.W = (matrix.M12 - matrix.M21) * half;
\r
495 void Quaternion::RotationMatrix( Matrix% matrix, [Out] Quaternion% result )
\r
497 float scale = matrix.M11 + matrix.M22 + matrix.M33;
\r
501 float sqrt = static_cast<float>( Math::Sqrt( static_cast<double>(scale + 1.0f) ) );
\r
503 result.W = sqrt * 0.5f;
\r
504 sqrt = 0.5f / sqrt;
\r
506 result.X = (matrix.M23 - matrix.M32) * sqrt;
\r
507 result.Y = (matrix.M31 - matrix.M13) * sqrt;
\r
508 result.Z = (matrix.M12 - matrix.M21) * sqrt;
\r
512 if( (matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33) )
\r
514 float sqrt = static_cast<float>( Math::Sqrt( static_cast<double>(1.0f + matrix.M11 - matrix.M22 - matrix.M33) ) );
\r
515 float half = 0.5f / sqrt;
\r
517 result.X = 0.5f * sqrt;
\r
518 result.Y = (matrix.M12 + matrix.M21) * half;
\r
519 result.Z = (matrix.M13 + matrix.M31) * half;
\r
520 result.W = (matrix.M23 - matrix.M32) * half;
\r
524 if( matrix.M22 > matrix.M33 )
\r
526 float sqrt = static_cast<float>( Math::Sqrt( static_cast<double>(1.0f + matrix.M22 - matrix.M11 - matrix.M33) ) );
\r
527 float half = 0.5f / sqrt;
\r
529 result.X = (matrix.M21 + matrix.M12) * half;
\r
530 result.Y = 0.5f * sqrt;
\r
531 result.Z = (matrix.M32 + matrix.M23) * half;
\r
532 result.W = (matrix.M31 - matrix.M13) * half;
\r
536 float sqrt = static_cast<float>( Math::Sqrt( static_cast<double>(1.0f + matrix.M33 - matrix.M11 - matrix.M22) ) );
\r
537 float half = 0.5f / sqrt;
\r
539 result.X = (matrix.M31 + matrix.M13) * half;
\r
540 result.Y = (matrix.M32 + matrix.M23) * half;
\r
541 result.Z = 0.5f * sqrt;
\r
542 result.W = (matrix.M12 - matrix.M21) * half;
\r
545 Quaternion Quaternion::RotationYawPitchRoll( float yaw, float pitch, float roll )
\r
549 float halfRoll = roll * 0.5f;
\r
550 float sinRoll = static_cast<float>( Math::Sin( static_cast<double>( halfRoll ) ) );
\r
551 float cosRoll = static_cast<float>( Math::Cos( static_cast<double>( halfRoll ) ) );
\r
552 float halfPitch = pitch * 0.5f;
\r
553 float sinPitch = static_cast<float>( Math::Sin( static_cast<double>( halfPitch ) ) );
\r
554 float cosPitch = static_cast<float>( Math::Cos( static_cast<double>( halfPitch ) ) );
\r
555 float halfYaw = yaw * 0.5f;
\r
556 float sinYaw = static_cast<float>( Math::Sin( static_cast<double>( halfYaw ) ) );
\r
557 float cosYaw = static_cast<float>( Math::Cos( static_cast<double>( halfYaw ) ) );
\r
559 result.X = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);
\r
560 result.Y = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);
\r
561 result.Z = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);
\r
562 result.W = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);
\r
567 void Quaternion::RotationYawPitchRoll( float yaw, float pitch, float roll, [Out] Quaternion% result )
\r
569 float halfRoll = roll * 0.5f;
\r
570 float sinRoll = static_cast<float>( Math::Sin( static_cast<double>( halfRoll ) ) );
\r
571 float cosRoll = static_cast<float>( Math::Cos( static_cast<double>( halfRoll ) ) );
\r
572 float halfPitch = pitch * 0.5f;
\r
573 float sinPitch = static_cast<float>( Math::Sin( static_cast<double>( halfPitch ) ) );
\r
574 float cosPitch = static_cast<float>( Math::Cos( static_cast<double>( halfPitch ) ) );
\r
575 float halfYaw = yaw * 0.5f;
\r
576 float sinYaw = static_cast<float>( Math::Sin( static_cast<double>( halfYaw ) ) );
\r
577 float cosYaw = static_cast<float>( Math::Cos( static_cast<double>( halfYaw ) ) );
\r
579 result.X = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);
\r
580 result.Y = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);
\r
581 result.Z = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);
\r
582 result.W = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);
\r
585 Quaternion Quaternion::Slerp( Quaternion q1, Quaternion q2, float t )
\r
591 float dot = (q1.X * q2.X) + (q1.Y * q2.Y) + (q1.Z * q2.Z) + (q1.W * q2.W);
\r
600 if( dot > 0.999999f )
\r
602 inverse = 1.0f - t;
\r
603 opposite = flag ? -t : t;
\r
607 float acos = static_cast<float>( Math::Acos( static_cast<double>( dot ) ) );
\r
608 float invSin = static_cast<float>( ( 1.0f / Math::Sin( static_cast<double>( acos ) ) ) );
\r
610 inverse = ( static_cast<float>( Math::Sin( static_cast<double>( (1.0f - t) * acos ) ) ) ) * invSin;
\r
611 opposite = flag ? ( ( static_cast<float>( -Math::Sin( static_cast<double>( t * acos ) ) ) ) * invSin ) : ( ( static_cast<float>( Math::Sin( static_cast<double>( t * acos ) ) ) ) * invSin );
\r
614 result.X = (inverse * q1.X) + (opposite * q2.X);
\r
615 result.Y = (inverse * q1.Y) + (opposite * q2.Y);
\r
616 result.Z = (inverse * q1.Z) + (opposite * q2.Z);
\r
617 result.W = (inverse * q1.W) + (opposite * q2.W);
\r
622 void Quaternion::Slerp( Quaternion% q1, Quaternion% q2, float t, [Out] Quaternion% result )
\r
626 float dot = (q1.X * q2.X) + (q1.Y * q2.Y) + (q1.Z * q2.Z) + (q1.W * q2.W);
\r
635 if( dot > 0.999999f )
\r
637 inverse = 1.0f - t;
\r
638 opposite = flag ? -t : t;
\r
642 float acos = static_cast<float>( Math::Acos( static_cast<double>( dot ) ) );
\r
643 float invSin = static_cast<float>( ( 1.0f / Math::Sin( static_cast<double>( acos ) ) ) );
\r
645 inverse = ( static_cast<float>( Math::Sin( static_cast<double>( (1.0f - t) * acos ) ) ) ) * invSin;
\r
646 opposite = flag ? ( ( static_cast<float>( -Math::Sin( static_cast<double>( t * acos ) ) ) ) * invSin ) : ( ( static_cast<float>( Math::Sin( static_cast<double>( t * acos ) ) ) ) * invSin );
\r
649 result.X = (inverse * q1.X) + (opposite * q2.X);
\r
650 result.Y = (inverse * q1.Y) + (opposite * q2.Y);
\r
651 result.Z = (inverse * q1.Z) + (opposite * q2.Z);
\r
652 result.W = (inverse * q1.W) + (opposite * q2.W);
\r
655 Quaternion Quaternion::Squad( Quaternion q1, Quaternion a, Quaternion b, Quaternion c, float t )
\r
659 D3DXQuaternionSquad( (D3DXQUATERNION*) &result, (D3DXQUATERNION*) &q1, (D3DXQUATERNION*) &a,
\r
660 (D3DXQUATERNION*) &b, (D3DXQUATERNION*) &c, t );
\r
665 void Quaternion::Squad( Quaternion% q1, Quaternion% a, Quaternion% b, Quaternion% c, float t, [Out] Quaternion% result )
\r
667 pin_ptr<Quaternion> pin1 = &q1;
\r
668 pin_ptr<Quaternion> pinA = &a;
\r
669 pin_ptr<Quaternion> pinB = &b;
\r
670 pin_ptr<Quaternion> pinC = &c;
\r
671 pin_ptr<Quaternion> pinResult = &result;
\r
673 D3DXQuaternionSquad( (D3DXQUATERNION*) pinResult, (D3DXQUATERNION*) pin1, (D3DXQUATERNION*) pinA,
\r
674 (D3DXQUATERNION*) pinB, (D3DXQUATERNION*) pinC, t );
\r
677 array<Quaternion>^ Quaternion::SquadSetup( Quaternion source1, Quaternion source2, Quaternion source3, Quaternion source4 )
\r
679 Quaternion result1;
\r
680 Quaternion result2;
\r
681 Quaternion result3;
\r
682 array<Quaternion>^ results = gcnew array<Quaternion>( 3 );
\r
684 D3DXQuaternionSquadSetup( (D3DXQUATERNION*) &result1, (D3DXQUATERNION*) &result2, (D3DXQUATERNION*) &result3,
\r
685 (D3DXQUATERNION*) &source1, (D3DXQUATERNION*) &source2, (D3DXQUATERNION*) &source3, (D3DXQUATERNION*) &source4 );
\r
687 results[0] = result1;
\r
688 results[1] = result2;
\r
689 results[2] = result3;
\r
693 Quaternion Quaternion::Subtract( Quaternion left, Quaternion right )
\r
696 result.X = left.X - right.X;
\r
697 result.Y = left.Y - right.Y;
\r
698 result.Z = left.Z - right.Z;
\r
699 result.W = left.W - right.W;
\r
703 void Quaternion::Subtract( Quaternion% left, Quaternion% right, [Out] Quaternion% result )
\r
705 result.X = left.X - right.X;
\r
706 result.Y = left.Y - right.Y;
\r
707 result.Z = left.Z - right.Z;
\r
708 result.W = left.W - right.W;
\r
711 Quaternion Quaternion::operator * (Quaternion left, Quaternion right)
\r
713 Quaternion quaternion;
\r
718 float rx = right.X;
\r
719 float ry = right.Y;
\r
720 float rz = right.Z;
\r
721 float rw = right.W;
\r
723 quaternion.X = (rx * lw + lx * rw + ry * lz) - (rz * ly);
\r
724 quaternion.Y = (ry * lw + ly * rw + rz * lx) - (rx * lz);
\r
725 quaternion.Z = (rz * lw + lz * rw + rx * ly) - (ry * lx);
\r
726 quaternion.W = (rw * lw) - (rx * lx + ry * ly + rz * lz);
\r
731 Quaternion Quaternion::operator * (Quaternion quaternion, float scale)
\r
734 result.X = quaternion.X * scale;
\r
735 result.Y = quaternion.Y * scale;
\r
736 result.Z = quaternion.Z * scale;
\r
737 result.W = quaternion.W * scale;
\r
741 Quaternion Quaternion::operator * (float scale, Quaternion quaternion)
\r
744 result.X = quaternion.X * scale;
\r
745 result.Y = quaternion.Y * scale;
\r
746 result.Z = quaternion.Z * scale;
\r
747 result.W = quaternion.W * scale;
\r
751 Quaternion Quaternion::operator / (Quaternion lhs, float rhs)
\r
754 result.X = lhs.X / rhs;
\r
755 result.Y = lhs.Y / rhs;
\r
756 result.Z = lhs.Z / rhs;
\r
757 result.W = lhs.W / rhs;
\r
761 Quaternion Quaternion::operator + (Quaternion lhs, Quaternion rhs)
\r
764 result.X = lhs.X + rhs.X;
\r
765 result.Y = lhs.Y + rhs.Y;
\r
766 result.Z = lhs.Z + rhs.Z;
\r
767 result.W = lhs.W + rhs.W;
\r
771 Quaternion Quaternion::operator - (Quaternion lhs, Quaternion rhs)
\r
774 result.X = lhs.X - rhs.X;
\r
775 result.Y = lhs.Y - rhs.Y;
\r
776 result.Z = lhs.Z - rhs.Z;
\r
777 result.W = lhs.W - rhs.W;
\r
781 Quaternion Quaternion::operator - (Quaternion quaternion)
\r
784 result.X = -quaternion.X;
\r
785 result.Y = -quaternion.Y;
\r
786 result.Z = -quaternion.Z;
\r
787 result.W = -quaternion.W;
\r
791 bool Quaternion::operator == ( Quaternion left, Quaternion right )
\r
793 return Quaternion::Equals( left, right );
\r
796 bool Quaternion::operator != ( Quaternion left, Quaternion right )
\r
798 return !Quaternion::Equals( left, right );
\r
801 String^ Quaternion::ToString()
\r
803 return String::Format( CultureInfo::CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}", X.ToString(CultureInfo::CurrentCulture),
\r
804 Y.ToString(CultureInfo::CurrentCulture), Z.ToString(CultureInfo::CurrentCulture),
\r
805 W.ToString(CultureInfo::CurrentCulture) );
\r
808 int Quaternion::GetHashCode()
\r
810 return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
\r
813 bool Quaternion::Equals( Object^ value )
\r
815 if( value == nullptr )
\r
818 if( value->GetType() != GetType() )
\r
821 return Equals( safe_cast<Quaternion>( value ) );
\r
824 bool Quaternion::Equals( Quaternion value )
\r
826 return ( X == value.X && Y == value.Y && Z == value.Z && W == value.W );
\r
829 bool Quaternion::Equals( Quaternion% value1, Quaternion% value2 )
\r
831 return ( value1.X == value2.X && value1.Y == value2.Y && value1.Z == value2.Z && value1.W == value2.W );
\r