diff options
Diffstat (limited to 'libraries/ModifiedBulletX/ModifiedBulletX/LinearMath/Quaternion.cs')
-rw-r--r-- | libraries/ModifiedBulletX/ModifiedBulletX/LinearMath/Quaternion.cs | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/LinearMath/Quaternion.cs b/libraries/ModifiedBulletX/ModifiedBulletX/LinearMath/Quaternion.cs new file mode 100644 index 0000000..5425a05 --- /dev/null +++ b/libraries/ModifiedBulletX/ModifiedBulletX/LinearMath/Quaternion.cs | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru | ||
3 | Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com | ||
4 | |||
5 | This software is provided 'as-is', without any express or implied | ||
6 | warranty. In no event will the authors be held liable for any damages | ||
7 | arising from the use of this software. | ||
8 | |||
9 | Permission is granted to anyone to use this software for any purpose, | ||
10 | including commercial applications, and to alter it and redistribute it | ||
11 | freely, subject to the following restrictions: | ||
12 | |||
13 | 1. The origin of this software must not be misrepresented; you must not | ||
14 | claim that you wrote the original software. If you use this software | ||
15 | in a product, an acknowledgment in the product documentation would be | ||
16 | appreciated but is not required. | ||
17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
18 | misrepresented as being the original software. | ||
19 | 3. This notice may not be removed or altered from any source distribution. | ||
20 | */ | ||
21 | |||
22 | using System; | ||
23 | using System.Collections.Generic; | ||
24 | using System.Text; | ||
25 | |||
26 | namespace XnaDevRu.BulletX.LinearMath | ||
27 | { | ||
28 | internal class Quaternion : QuadWord | ||
29 | { | ||
30 | public Quaternion() { } | ||
31 | |||
32 | public Quaternion(float x, float y, float z, float w) | ||
33 | : base(x, y, z, w) { } | ||
34 | |||
35 | public Quaternion(Vector3 axis, float angle) | ||
36 | { | ||
37 | SetRotation(axis, angle); | ||
38 | } | ||
39 | |||
40 | public Quaternion(float yaw, float pitch, float roll) | ||
41 | { | ||
42 | SetEuler(yaw, pitch, roll); | ||
43 | } | ||
44 | |||
45 | public void SetRotation(Vector3 axis, float angle) | ||
46 | { | ||
47 | float d = axis.Length(); | ||
48 | if (d == 0) throw new DivideByZeroException(); | ||
49 | float s = (float)Math.Sin(angle * 0.5f) / d; | ||
50 | X = axis.X * s; | ||
51 | Y = axis.Y * s; | ||
52 | Z = axis.Z * s; | ||
53 | W = (float)Math.Cos(angle * 0.5f); | ||
54 | } | ||
55 | |||
56 | public void SetEuler(float yaw, float pitch, float roll) | ||
57 | { | ||
58 | float halfYaw = yaw * 0.5f; | ||
59 | float halfPitch = pitch * 0.5f; | ||
60 | float halfRoll = roll * 0.5f; | ||
61 | float cosYaw = (float)Math.Cos(halfYaw); | ||
62 | float sinYaw = (float)Math.Sin(halfYaw); | ||
63 | float cosPitch = (float)Math.Cos(halfPitch); | ||
64 | float sinPitch = (float)Math.Sin(halfPitch); | ||
65 | float cosRoll = (float)Math.Cos(halfRoll); | ||
66 | float sinRoll = (float)Math.Sin(halfRoll); | ||
67 | X = cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw; | ||
68 | Y = cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw; | ||
69 | Z = sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw; | ||
70 | W = cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw; | ||
71 | } | ||
72 | |||
73 | public float LengthSquared() | ||
74 | { | ||
75 | return Dot(this, this); | ||
76 | } | ||
77 | |||
78 | public float Length() | ||
79 | { | ||
80 | return (float)Math.Sqrt(LengthSquared()); | ||
81 | } | ||
82 | |||
83 | public float Angle() | ||
84 | { | ||
85 | return 2f * (float)Math.Acos(W); | ||
86 | } | ||
87 | |||
88 | public static float Angle(Quaternion a, Quaternion b) | ||
89 | { | ||
90 | float s = (float)Math.Sqrt(a.LengthSquared() * b.LengthSquared()); | ||
91 | if (s == 0) throw new DivideByZeroException(); | ||
92 | return (float)Math.Acos(Dot(a, b) / s); | ||
93 | } | ||
94 | |||
95 | public static Quaternion Farthest(Quaternion a, Quaternion b) | ||
96 | { | ||
97 | Quaternion diff, sum; | ||
98 | diff = a - b; | ||
99 | sum = a + b; | ||
100 | if (Dot(diff, diff) > Dot(sum, sum)) | ||
101 | return b; | ||
102 | return -b; | ||
103 | } | ||
104 | |||
105 | public static Quaternion Slerp(Quaternion a, Quaternion b, float c) | ||
106 | { | ||
107 | float theta = Angle(a, b); | ||
108 | if (theta != 0) | ||
109 | { | ||
110 | float d = 1f / (float)Math.Sin(theta); | ||
111 | float s0 = (float)Math.Sin((1f - c) * theta); | ||
112 | float s1 = (float)Math.Sin(c * theta); | ||
113 | return new Quaternion( | ||
114 | (a.X * s0 + b.X * s1) * d, | ||
115 | (a.Y * s0 + b.Y * s1) * d, | ||
116 | (a.Z * s0 + b.Z * s1) * d, | ||
117 | (a.W * s0 + b.W * s1) * d); | ||
118 | } | ||
119 | else | ||
120 | { | ||
121 | return a; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | public static Quaternion Inverse(Quaternion a) | ||
126 | { | ||
127 | return new Quaternion(a.X, a.Y, a.Z, -a.W); | ||
128 | } | ||
129 | |||
130 | public static Quaternion Normalize(Quaternion a) | ||
131 | { | ||
132 | return a / a.Length(); | ||
133 | } | ||
134 | |||
135 | public static float Dot(Quaternion a, Quaternion b) | ||
136 | { | ||
137 | return a.X * b.X + a.Y * b.Y + a.Z * b.Z + a.W * b.W; | ||
138 | } | ||
139 | |||
140 | public static Quaternion operator +(Quaternion a, Quaternion b) | ||
141 | { | ||
142 | return new Quaternion(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W); | ||
143 | } | ||
144 | |||
145 | public static Quaternion operator -(Quaternion a, Quaternion b) | ||
146 | { | ||
147 | return new Quaternion(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W); | ||
148 | } | ||
149 | |||
150 | public static Quaternion operator -(Quaternion a) | ||
151 | { | ||
152 | return new Quaternion(-a.X, -a.Y, -a.Z, -a.W); | ||
153 | } | ||
154 | |||
155 | public static Quaternion operator *(Quaternion a, float b) | ||
156 | { | ||
157 | return new Quaternion(a.X * b, a.Y * b, a.Z * b, a.W * b); | ||
158 | } | ||
159 | |||
160 | public static Quaternion operator *(Quaternion a, Quaternion b) | ||
161 | { | ||
162 | return new Quaternion( | ||
163 | a.W * b.X + a.X * b.W + a.Y * b.Z - a.Z * b.Y, | ||
164 | a.W * b.Y + a.Y * b.W + a.Z * b.X - a.X * b.Z, | ||
165 | a.W * b.Z + a.Z * b.W + a.X * b.Y - a.Y * b.X, | ||
166 | a.W * b.W - a.X * b.X - a.Y * b.Y - a.Z * b.Z); | ||
167 | } | ||
168 | |||
169 | public static Quaternion operator *(Quaternion a, Vector3 b) | ||
170 | { | ||
171 | return new Quaternion( | ||
172 | a.W * b.X + a.Y * b.Z - a.Z * b.Y, | ||
173 | a.W * b.Y + a.Z * b.X - a.X * b.Z, | ||
174 | a.W * b.Z + a.X * b.Y - a.Y * b.X, | ||
175 | -a.X * b.X - a.Y * b.Y - a.Z * b.Z); | ||
176 | } | ||
177 | |||
178 | public static Quaternion operator *(Vector3 w, Quaternion q) | ||
179 | { | ||
180 | return new Quaternion( | ||
181 | w.X * q.W + w.Y * q.Z - w.Z * q.Y, | ||
182 | w.Y * q.W + w.Z * q.X - w.X * q.Z, | ||
183 | w.Z * q.W + w.X * q.Y - w.Y * q.X, | ||
184 | -w.X * q.X - w.Y * q.Y - w.Z * q.Z); | ||
185 | } | ||
186 | |||
187 | public static Quaternion operator /(Quaternion a, float b) | ||
188 | { | ||
189 | if (b == 0) throw new DivideByZeroException(); | ||
190 | return new Quaternion(a.X / b, a.Y / b, a.Z / b, a.W / b); | ||
191 | } | ||
192 | |||
193 | public static explicit operator MonoXnaCompactMaths.Quaternion(Quaternion a) | ||
194 | { | ||
195 | return new MonoXnaCompactMaths.Quaternion(a.X, a.Y, a.Z, a.W); | ||
196 | } | ||
197 | } | ||
198 | } | ||