source: OniSplit/Math/Vector3.cs@ 1189

Last change on this file since 1189 was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 10.7 KB
Line 
1using System;
2
3namespace Oni
4{
5 internal struct Vector3 : IEquatable<Vector3>
6 {
7 public float X;
8 public float Y;
9 public float Z;
10
11 public Vector3(float all)
12 {
13 X = all;
14 Y = all;
15 Z = all;
16 }
17
18 public Vector3(float x, float y, float z)
19 {
20 X = x;
21 Y = y;
22 Z = z;
23 }
24
25 public Vector3(float[] values, int index = 0)
26 {
27 int i = index * 3;
28
29 X = values[i + 0];
30 Y = values[i + 1];
31 Z = values[i + 2];
32 }
33
34 public void CopyTo(float[] values, int index = 0)
35 {
36 values[index + 0] = X;
37 values[index + 1] = Y;
38 values[index + 2] = Z;
39 }
40
41 public Vector2 XZ => new Vector2(X, Z);
42
43 public static Vector3 operator +(Vector3 v1, Vector3 v2)
44 {
45 v1.X += v2.X;
46 v1.Y += v2.Y;
47 v1.Z += v2.Z;
48
49 return v1;
50 }
51
52 public static Vector3 operator -(Vector3 v1, Vector3 v2)
53 {
54 v1.X -= v2.X;
55 v1.Y -= v2.Y;
56 v1.Z -= v2.Z;
57
58 return v1;
59 }
60
61 public static Vector3 operator -(Vector3 v)
62 {
63 v.X = -v.X;
64 v.Y = -v.Y;
65 v.Z = -v.Z;
66
67 return v;
68 }
69
70 public static Vector3 operator *(Vector3 v, float s)
71 {
72 v.X *= s;
73 v.Y *= s;
74 v.Z *= s;
75
76 return v;
77 }
78
79 public static Vector3 operator *(float s, Vector3 v)
80 {
81 v.X *= s;
82 v.Y *= s;
83 v.Z *= s;
84
85 return v;
86 }
87
88 public static Vector3 operator *(Vector3 v1, Vector3 v2) => new Vector3
89 {
90 X = v1.X * v2.X,
91 Y = v1.Y * v2.Y,
92 Z = v1.Z * v2.Z,
93 };
94
95 public static Vector3 operator /(Vector3 v, float s) => v * (1.0f / s);
96
97 public static Vector3 operator /(Vector3 v1, Vector3 v2) => new Vector3
98 {
99 X = v1.X /= v2.X,
100 Y = v1.Y /= v2.Y,
101 Z = v1.Z /= v2.Z
102 };
103
104 public static void Add(ref Vector3 v1, ref Vector3 v2, out Vector3 r)
105 {
106 r.X = v1.X + v2.X;
107 r.Y = v1.Y + v2.Y;
108 r.Z = v1.Z + v2.Z;
109 }
110
111 public static void Substract(ref Vector3 v1, ref Vector3 v2, out Vector3 r)
112 {
113 r.X = v1.X - v2.X;
114 r.Y = v1.Y - v2.Y;
115 r.Z = v1.Z - v2.Z;
116 }
117
118 public static void Multiply(ref Vector3 v, float f, out Vector3 r)
119 {
120 r.X = v.X * f;
121 r.Y = v.Y * f;
122 r.Z = v.Z * f;
123 }
124
125 public void Scale(float scale)
126 {
127 X *= scale;
128 Y *= scale;
129 Z *= scale;
130 }
131
132 public static Vector3 Clamp(Vector3 v, Vector3 min, Vector3 max)
133 {
134 Vector3 r;
135
136 float x = v.X;
137 x = (x > max.X) ? max.X : x;
138 x = (x < min.X) ? min.X : x;
139
140 float y = v.Y;
141 y = (y > max.Y) ? max.Y : y;
142 y = (y < min.Y) ? min.Y : y;
143
144 float z = v.Z;
145 z = (z > max.Z) ? max.Z : z;
146 z = (z < min.Z) ? min.Z : z;
147
148 r.X = x;
149 r.Y = y;
150 r.Z = z;
151
152 return r;
153 }
154
155 public static Vector3 Cross(Vector3 v1, Vector3 v2)
156 {
157 return new Vector3(
158 v1.Y * v2.Z - v1.Z * v2.Y,
159 v1.Z * v2.X - v1.X * v2.Z,
160 v1.X * v2.Y - v1.Y * v2.X);
161 }
162
163 public static void Cross(ref Vector3 v1, ref Vector3 v2, out Vector3 r)
164 {
165 r = new Vector3(
166 v1.Y * v2.Z - v1.Z * v2.Y,
167 v1.Z * v2.X - v1.X * v2.Z,
168 v1.X * v2.Y - v1.Y * v2.X);
169 }
170
171 public static float Dot(Vector3 v1, Vector3 v2)
172 {
173 return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
174 }
175
176 public static float Dot(ref Vector3 v1, ref Vector3 v2) => v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
177
178 public float Dot(ref Vector3 v) => X * v.X + Y * v.Y + Z * v.Z;
179
180 public static Vector3 Transform(Vector3 v, Quaternion q)
181 {
182 Quaternion vq = new Quaternion(v, 0.0f);
183 q = q * vq * Quaternion.Conjugate(q);
184 return new Vector3(q.X, q.Y, q.Z);
185 }
186
187 public static Vector3 Transform(Vector3 v, ref Matrix m)
188 {
189 return new Vector3(
190 v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31 + m.M41,
191 v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32 + m.M42,
192 v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33 + m.M43);
193 }
194
195 public static void Transform(ref Vector3 v, ref Matrix m, out Vector3 r)
196 {
197 r.X = v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31 + m.M41;
198 r.Y = v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32 + m.M42;
199 r.Z = v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33 + m.M43;
200 }
201
202 public static Vector3 TransformNormal(Vector3 v, ref Matrix m)
203 {
204 return new Vector3(
205 v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31,
206 v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32,
207 v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33);
208 }
209
210 public static void Transform(Vector3[] v, ref Matrix m, Vector3[] r)
211 {
212 for (int i = 0; i < v.Length; i++)
213 {
214 float x = v[i].X;
215 float y = v[i].Y;
216 float z = v[i].Z;
217
218 r[i].X = x * m.M11 + y * m.M21 + z * m.M31 + m.M41;
219 r[i].Y = x * m.M12 + y * m.M22 + z * m.M32 + m.M42;
220 r[i].Z = x * m.M13 + y * m.M23 + z * m.M33 + m.M43;
221 }
222 }
223
224 public static Vector3[] Transform(Vector3[] v, ref Matrix m)
225 {
226 var r = new Vector3[v.Length];
227 Transform(v, ref m, r);
228 return r;
229 }
230
231 public static void TransformNormal(Vector3[] v, ref Matrix m, Vector3[] r)
232 {
233 for (int i = 0; i < v.Length; i++)
234 {
235 float x = v[i].X;
236 float y = v[i].Y;
237 float z = v[i].Z;
238
239 r[i].X = x * m.M11 + y * m.M21 + z * m.M31;
240 r[i].Y = x * m.M12 + y * m.M22 + z * m.M32;
241 r[i].Z = x * m.M13 + y * m.M23 + z * m.M33;
242 }
243 }
244
245 public static Vector3[] TransformNormal(Vector3[] v, ref Matrix m)
246 {
247 var r = new Vector3[v.Length];
248 TransformNormal(v, ref m, r);
249 return r;
250 }
251
252 public static Vector3 Min(Vector3 v1, Vector3 v2)
253 {
254 if (v2.X < v1.X)
255 v1.X = v2.X;
256
257 if (v2.Y < v1.Y)
258 v1.Y = v2.Y;
259
260 if (v2.Z < v1.Z)
261 v1.Z = v2.Z;
262
263 return v1;
264 }
265
266 public static void Min(ref Vector3 v1, ref Vector3 v2, out Vector3 r)
267 {
268 r.X = (v1.X < v2.X) ? v1.X : v2.X;
269 r.Y = (v1.Y < v2.Y) ? v1.Y : v2.Y;
270 r.Z = (v1.Z < v2.Z) ? v1.Z : v2.Z;
271 }
272
273 public static Vector3 Max(Vector3 v1, Vector3 v2)
274 {
275 if (v2.X > v1.X)
276 v1.X = v2.X;
277
278 if (v2.Y > v1.Y)
279 v1.Y = v2.Y;
280
281 if (v2.Z > v1.Z)
282 v1.Z = v2.Z;
283
284 return v1;
285 }
286
287 public static void Max(ref Vector3 v1, ref Vector3 v2, out Vector3 r)
288 {
289 r.X = (v1.X > v2.X) ? v1.X : v2.X;
290 r.Y = (v1.Y > v2.Y) ? v1.Y : v2.Y;
291 r.Z = (v1.Z > v2.Z) ? v1.Z : v2.Z;
292 }
293
294 public static Vector3 Normalize(Vector3 v) => v * (1.0f / v.Length());
295
296 public void Normalize()
297 {
298 float k = 1.0f / Length();
299
300 X *= k;
301 Y *= k;
302 Z *= k;
303 }
304
305 public float LengthSquared() => X * X + Y * Y + Z * Z;
306
307 public float Length() => FMath.Sqrt(LengthSquared());
308
309 public static float Distance(Vector3 v1, Vector3 v2) => FMath.Sqrt((v2 - v1).LengthSquared());
310
311 public static float DistanceSquared(Vector3 v1, Vector3 v2) => (v2 - v1).LengthSquared();
312
313 public static Vector3 Lerp(Vector3 v1, Vector3 v2, float amount) => v1 + (v2 - v1) * amount;
314
315 public static bool EqualsEps(Vector3 v1, Vector3 v2)
316 {
317 Vector3 d = v2 - v1;
318
319 float dx = Math.Abs(d.X);
320 float dy = Math.Abs(d.Y);
321 float dz = Math.Abs(d.Z);
322
323 return (dx < 0.0001f && dy < 0.0001f && dz < 0.0001f);
324 }
325
326 public static bool operator ==(Vector3 v1, Vector3 v2) => v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z;
327 public static bool operator !=(Vector3 v1, Vector3 v2) => v1.X != v2.X || v1.Y != v2.Y || v1.Z != v2.Z;
328
329 public bool Equals(Vector3 other) => X == other.X && Y == other.Y && Z == other.Z;
330 public override bool Equals(object obj) => obj is Vector3 && Equals((Vector3)obj);
331 public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode();
332
333 public override string ToString() => $"{{{X} {Y} {Z}}}";
334
335 private static Vector3 zero = new Vector3();
336 private static Vector3 one = new Vector3(1.0f);
337 private static Vector3 up = new Vector3(0.0f, 1.0f, 0.0f);
338 private static Vector3 down = new Vector3(0.0f, -1.0f, 0.0f);
339 private static Vector3 right = new Vector3(1.0f, 0.0f, 0.0f);
340 private static Vector3 left = new Vector3(-1.0f, 0.0f, 0.0f);
341 private static Vector3 backward = new Vector3(0.0f, 0.0f, 1.0f);
342 private static Vector3 forward = new Vector3(0.0f, 0.0f, -1.0f);
343
344 public static Vector3 Zero => zero;
345 public static Vector3 One => one;
346 public static Vector3 Up => up;
347 public static Vector3 Down => down;
348 public static Vector3 Left => left;
349 public static Vector3 Right => right;
350 public static Vector3 Backward => backward;
351 public static Vector3 Forward => forward;
352 public static Vector3 UnitX => right;
353 public static Vector3 UnitY => up;
354 public static Vector3 UnitZ => backward;
355
356 public float this[int i]
357 {
358 get
359 {
360 if (i == 1)
361 return Y;
362 else if (i < 1)
363 return X;
364 else
365 return Z;
366 }
367 }
368 }
369}
Note: See TracBrowser for help on using the repository browser.