Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
Quaternion.cs
浏览该文件的文档.
1using System.Globalization;
2
3namespace Engine {
4 public struct Quaternion : IEquatable<Quaternion> {
5 public float X;
6
7 public float Y;
8
9 public float Z;
10
11 public float W;
12
13 public static readonly Quaternion Identity = new(0f, 0f, 0f, 1f);
14
15 public Quaternion(float x, float y, float z, float w) {
16 X = x;
17 Y = y;
18 Z = z;
19 W = w;
20 }
21
22 public Quaternion(Vector3 v, float s) {
23 X = v.X;
24 Y = v.Y;
25 Z = v.Z;
26 W = s;
27 }
28
29 public static implicit operator Quaternion((float X, float Y, float Z, float W) v) => new(v.X, v.Y, v.Z, v.W);
30
31 public override bool Equals(object obj) => obj is Quaternion quaternion && Equals(quaternion);
32
33 public override int GetHashCode() => X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
34
35 public override string ToString() =>
36 $"{X.ToString(CultureInfo.InvariantCulture)},{Y.ToString(CultureInfo.InvariantCulture)},{Z.ToString(CultureInfo.InvariantCulture)},{W.ToString(CultureInfo.InvariantCulture)}";
37
38 public bool Equals(Quaternion other) => X == other.X && Y == other.Y && Z == other.Z && W == other.W;
39
40 public static Quaternion Conjugate(Quaternion q) => new(0f - q.X, 0f - q.Y, 0f - q.Z, q.W);
41
42 public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle) {
43 float x = angle * 0.5f;
44 float num = MathF.Sin(x);
45 float w = MathF.Cos(x);
46 Quaternion result = default;
47 result.X = axis.X * num;
48 result.Y = axis.Y * num;
49 result.Z = axis.Z * num;
50 result.W = w;
51 return result;
52 }
53
55 float num = m.M11 + m.M22 + m.M33;
56 Quaternion result = default;
57 if (num > 0f) {
58 float num2 = MathF.Sqrt(num + 1f);
59 result.W = num2 * 0.5f;
60 num2 = 0.5f / num2;
61 result.X = (m.M23 - m.M32) * num2;
62 result.Y = (m.M31 - m.M13) * num2;
63 result.Z = (m.M12 - m.M21) * num2;
64 return result;
65 }
66 if (m.M11 >= m.M22
67 && m.M11 >= m.M33) {
68 float num3 = MathF.Sqrt(1f + m.M11 - m.M22 - m.M33);
69 float num4 = 0.5f / num3;
70 result.X = 0.5f * num3;
71 result.Y = (m.M12 + m.M21) * num4;
72 result.Z = (m.M13 + m.M31) * num4;
73 result.W = (m.M23 - m.M32) * num4;
74 return result;
75 }
76 if (m.M22 > m.M33) {
77 float num5 = MathF.Sqrt(1f + m.M22 - m.M11 - m.M33);
78 float num6 = 0.5f / num5;
79 result.X = (m.M21 + m.M12) * num6;
80 result.Y = 0.5f * num5;
81 result.Z = (m.M32 + m.M23) * num6;
82 result.W = (m.M31 - m.M13) * num6;
83 return result;
84 }
85 float num7 = MathF.Sqrt(1f + m.M33 - m.M11 - m.M22);
86 float num8 = 0.5f / num7;
87 result.X = (m.M31 + m.M13) * num8;
88 result.Y = (m.M32 + m.M23) * num8;
89 result.Z = 0.5f * num7;
90 result.W = (m.M12 - m.M21) * num8;
91 return result;
92 }
93
94 public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll) {
95 float x = roll * 0.5f;
96 float x2 = pitch * 0.5f;
97 float x3 = yaw * 0.5f;
98 float num = MathF.Sin(x);
99 float num2 = MathF.Cos(x);
100 float num3 = MathF.Sin(x2);
101 float num4 = MathF.Cos(x2);
102 float num5 = MathF.Sin(x3);
103 float num6 = MathF.Cos(x3);
104 return new Quaternion(
105 num6 * num3 * num2 + num5 * num4 * num,
106 num5 * num4 * num2 - num6 * num3 * num,
107 num6 * num4 * num - num5 * num3 * num2,
108 num6 * num4 * num2 + num5 * num3 * num
109 );
110 }
111
112 public static float Dot(Quaternion q1, Quaternion q2) => q1.X * q2.X + q1.Y * q2.Y + q1.Z * q2.Z + q1.W * q2.W;
113
114 public static Quaternion Inverse(Quaternion q) {
115 float num = q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W;
116 float num2 = 1f / num;
117 Quaternion result = default;
118 result.X = (0f - q.X) * num2;
119 result.Y = (0f - q.Y) * num2;
120 result.Z = (0f - q.Z) * num2;
121 result.W = q.W * num2;
122 return result;
123 }
124
125 public float Length() => MathF.Sqrt(LengthSquared());
126
127 public float LengthSquared() => X * X + Y * Y + Z * Z + W * W;
128
129 public static Quaternion Lerp(Quaternion q1, Quaternion q2, float f) {
130 float num = 1f - f;
131 Quaternion result = default;
132 if (q1.X * q2.X + q1.Y * q2.Y + q1.Z * q2.Z + q1.W * q2.W >= 0f) {
133 result.X = num * q1.X + f * q2.X;
134 result.Y = num * q1.Y + f * q2.Y;
135 result.Z = num * q1.Z + f * q2.Z;
136 result.W = num * q1.W + f * q2.W;
137 }
138 else {
139 result.X = num * q1.X - f * q2.X;
140 result.Y = num * q1.Y - f * q2.Y;
141 result.Z = num * q1.Z - f * q2.Z;
142 result.W = num * q1.W - f * q2.W;
143 }
144 float num2 = 1f / result.Length();
145 result.X *= num2;
146 result.Y *= num2;
147 result.Z *= num2;
148 result.W *= num2;
149 return result;
150 }
151
152 public static Quaternion Slerp(Quaternion q1, Quaternion q2, float f) {
153 float num = q1.X * q2.X + q1.Y * q2.Y + q1.Z * q2.Z + q1.W * q2.W;
154 bool flag = false;
155 if (num < 0f) {
156 flag = true;
157 num = 0f - num;
158 }
159 float num2;
160 float num3;
161 if (num > 0.999999f) {
162 num2 = 1f - f;
163 num3 = flag ? 0f - f : f;
164 }
165 else {
166 float num4 = MathF.Acos(num);
167 float num5 = 1f / MathF.Sin(num4);
168 num2 = MathF.Sin((1f - f) * num4) * num5;
169 num3 = flag ? (0f - MathF.Sin(f * num4)) * num5 : MathF.Sin(f * num4) * num5;
170 }
171 Quaternion result = default;
172 result.X = num2 * q1.X + num3 * q2.X;
173 result.Y = num2 * q1.Y + num3 * q2.Y;
174 result.Z = num2 * q1.Z + num3 * q2.Z;
175 result.W = num2 * q1.W + num3 * q2.W;
176 return result;
177 }
178
179 public static Quaternion Normalize(Quaternion q) {
180 float num = q.Length();
181 return num == 0f ? Identity : q / num;
182 }
183
184 public Matrix ToMatrix() {
185 float num = X * X;
186 float num2 = Y * Y;
187 float num3 = Z * Z;
188 float num4 = X * Y;
189 float num5 = Z * W;
190 float num6 = X * Z;
191 float num7 = Y * W;
192 float num8 = Y * Z;
193 float num9 = X * W;
194 Matrix result = default;
195 result.M11 = 1f - 2f * (num2 + num3);
196 result.M12 = 2f * (num4 + num5);
197 result.M13 = 2f * (num6 - num7);
198 result.M14 = 0f;
199 result.M21 = 2f * (num4 - num5);
200 result.M22 = 1f - 2f * (num3 + num);
201 result.M23 = 2f * (num8 + num9);
202 result.M24 = 0f;
203 result.M31 = 2f * (num6 + num7);
204 result.M32 = 2f * (num8 - num9);
205 result.M33 = 1f - 2f * (num2 + num);
206 result.M34 = 0f;
207 result.M41 = 0f;
208 result.M42 = 0f;
209 result.M43 = 0f;
210 result.M44 = 1f;
211 return result;
212 }
213
214 public Vector3 GetRightVector() => new(1f - 2f * (Y * Y + Z * Z), 2f * (X * Y + Z * W), 2f * (X * Z - W * Y));
215
216 public Vector3 GetUpVector() => new(2f * (X * Y - Z * W), 1f - 2f * (X * X + Z * Z), 2f * (Y * Z + X * W));
217
218 public Vector3 GetForwardVector() => new(-2f * (Y * W + X * Z), 2f * (X * W - Y * Z), 2f * (X * X + Y * Y) - 1f);
219
221 float num = -2f * (Y * W + X * Z);
222 float x = 2f * (X * W - Y * Z);
223 float num2 = 2f * (X * X + Y * Y) - 1f;
224 float y = 2f * (X * Y + Z * W);
225 float x2 = 1f - 2f * (X * X + Z * Z);
226 float x3 = MathF.Atan2(0f - num, 0f - num2);
227 float y2 = MathF.Asin(x);
228 float z = MathF.Atan2(y, x2);
229 return new Vector3(x3, y2, z);
230 }
231
232 public static bool operator ==(Quaternion q1, Quaternion q2) => q1.Equals(q2);
233
234 public static bool operator !=(Quaternion q1, Quaternion q2) => !q1.Equals(q2);
235
236 public static Quaternion operator +(Quaternion q) => q;
237
238 public static Quaternion operator -(Quaternion q) => new(0f - q.X, 0f - q.Y, 0f - q.Z, 0f - q.W);
239
240 public static Quaternion operator +(Quaternion q1, Quaternion q2) => new(q1.X + q2.X, q1.Y + q2.Y, q1.Z + q2.Z, q1.W + q2.W);
241
242 public static Quaternion operator -(Quaternion q1, Quaternion q2) => new(q1.X - q2.X, q1.Y - q2.Y, q1.Z - q2.Z, q1.W - q2.W);
243
245 float x = q1.X;
246 float y = q1.Y;
247 float z = q1.Z;
248 float w = q1.W;
249 float x2 = q2.X;
250 float y2 = q2.Y;
251 float z2 = q2.Z;
252 float w2 = q2.W;
253 float num = y * z2 - z * y2;
254 float num2 = z * x2 - x * z2;
255 float num3 = x * y2 - y * x2;
256 float num4 = x * x2 + y * y2 + z * z2;
257 Quaternion result = default;
258 result.X = x * w2 + x2 * w + num;
259 result.Y = y * w2 + y2 * w + num2;
260 result.Z = z * w2 + z2 * w + num3;
261 result.W = w * w2 - num4;
262 return result;
263 }
264
265 public static Quaternion operator *(Quaternion q, float s) => new(q.X * s, q.Y * s, q.Z * s, q.W * s);
266
268 float x = q1.X;
269 float y = q1.Y;
270 float z = q1.Z;
271 float w = q1.W;
272 float num = q2.X * q2.X + q2.Y * q2.Y + q2.Z * q2.Z + q2.W * q2.W;
273 float num2 = 1f / num;
274 float num3 = (0f - q2.X) * num2;
275 float num4 = (0f - q2.Y) * num2;
276 float num5 = (0f - q2.Z) * num2;
277 float num6 = q2.W * num2;
278 float num7 = y * num5 - z * num4;
279 float num8 = z * num3 - x * num5;
280 float num9 = x * num4 - y * num3;
281 float num10 = x * num3 + y * num4 + z * num5;
282 Quaternion result = default;
283 result.X = x * num6 + num3 * w + num7;
284 result.Y = y * num6 + num4 * w + num8;
285 result.Z = z * num6 + num5 * w + num9;
286 result.W = w * num6 - num10;
287 return result;
288 }
289
290 public static Quaternion operator /(Quaternion q, float d) {
291 float num = 1f / d;
292 return new Quaternion(q.X * num, q.Y * num, q.Z * num, q.W * num);
293 }
294
295 public static Quaternion FixNaN(Quaternion v) {
296 if (float.IsNaN(v.X)) {
297 v.X = 0;
298 }
299 if (float.IsNaN(v.Y)) {
300 v.Y = 0;
301 }
302 if (float.IsNaN(v.Z)) {
303 v.Z = 0;
304 }
305 if (float.IsNaN(v.W)) {
306 v.W = 0;
307 }
308 return v;
309 }
310
312 if (float.IsNaN(X)) {
313 X = 0;
314 }
315 if (float.IsNaN(Y)) {
316 Y = 0;
317 }
318 if (float.IsNaN(Z)) {
319 Z = 0;
320 }
321 if (float.IsNaN(W)) {
322 W = 0;
323 }
324 return this;
325 }
326 }
327}
Engine.Vector3 Vector3
static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
static float Dot(Quaternion q1, Quaternion q2)
static readonly Quaternion Identity
override string ToString()
static Quaternion Conjugate(Quaternion q)
Quaternion(float x, float y, float z, float w)
static Quaternion Inverse(Quaternion q)
static Quaternion CreateFromRotationMatrix(Matrix m)
static Quaternion operator*(Quaternion q1, Quaternion q2)
static bool operator==(Quaternion q1, Quaternion q2)
override int GetHashCode()
static Quaternion operator-(Quaternion q)
static Quaternion operator/(Quaternion q1, Quaternion q2)
static Quaternion Normalize(Quaternion q)
Quaternion(Vector3 v, float s)
static Quaternion Slerp(Quaternion q1, Quaternion q2, float f)
override bool Equals(object obj)
static Quaternion operator+(Quaternion q)
bool Equals(Quaternion other)
static bool operator!=(Quaternion q1, Quaternion q2)
static Quaternion FixNaN(Quaternion v)
static Quaternion Lerp(Quaternion q1, Quaternion q2, float f)
static Quaternion CreateFromAxisAngle(Vector3 axis, float angle)