| | | 1 | | using MemoryPack; |
| | | 2 | | using System; |
| | | 3 | | using System.Collections.Generic; |
| | | 4 | | using System.Runtime.CompilerServices; |
| | | 5 | | using System.Text.Json.Serialization; |
| | | 6 | | |
| | | 7 | | namespace FixedMathSharp; |
| | | 8 | | |
| | | 9 | | /// <summary> |
| | | 10 | | /// Represents a 4D vector with fixed-point precision. |
| | | 11 | | /// </summary> |
| | | 12 | | /// <remarks> |
| | | 13 | | /// This type is useful for generic 4D component math and homogeneous coordinates used by 4x4 transforms. |
| | | 14 | | /// </remarks> |
| | | 15 | | [Serializable] |
| | | 16 | | [MemoryPackable] |
| | | 17 | | public partial struct Vector4d : IEquatable<Vector4d>, IComparable<Vector4d>, IEqualityComparer<Vector4d> |
| | | 18 | | { |
| | | 19 | | #region Static Readonly Fields |
| | | 20 | | |
| | | 21 | | /// <summary> |
| | | 22 | | /// (1, 0, 0, 0) |
| | | 23 | | /// </summary> |
| | | 24 | | public static readonly Vector4d UnitX = new(1, 0, 0, 0); |
| | | 25 | | |
| | | 26 | | /// <summary> |
| | | 27 | | /// (0, 1, 0, 0) |
| | | 28 | | /// </summary> |
| | | 29 | | public static readonly Vector4d UnitY = new(0, 1, 0, 0); |
| | | 30 | | |
| | | 31 | | /// <summary> |
| | | 32 | | /// (0, 0, 1, 0) |
| | | 33 | | /// </summary> |
| | | 34 | | public static readonly Vector4d UnitZ = new(0, 0, 1, 0); |
| | | 35 | | |
| | | 36 | | /// <summary> |
| | | 37 | | /// (0, 0, 0, 1) |
| | | 38 | | /// </summary> |
| | | 39 | | public static readonly Vector4d UnitW = new(0, 0, 0, 1); |
| | | 40 | | |
| | | 41 | | /// <summary> |
| | | 42 | | /// (1, 1, 1, 1) |
| | | 43 | | /// </summary> |
| | | 44 | | public static readonly Vector4d One = new(1, 1, 1, 1); |
| | | 45 | | |
| | | 46 | | /// <summary> |
| | | 47 | | /// (-1, -1, -1, -1) |
| | | 48 | | /// </summary> |
| | | 49 | | public static readonly Vector4d Negative = new(-1, -1, -1, -1); |
| | | 50 | | |
| | | 51 | | /// <summary> |
| | | 52 | | /// (0, 0, 0, 0) |
| | | 53 | | /// </summary> |
| | | 54 | | public static readonly Vector4d Zero = new(0, 0, 0, 0); |
| | | 55 | | |
| | | 56 | | #endregion |
| | | 57 | | |
| | | 58 | | #region Fields |
| | | 59 | | |
| | | 60 | | /// <summary> |
| | | 61 | | /// The X component of the vector. |
| | | 62 | | /// </summary> |
| | | 63 | | [JsonInclude] |
| | | 64 | | [MemoryPackOrder(0)] |
| | | 65 | | public Fixed64 x; |
| | | 66 | | |
| | | 67 | | /// <summary> |
| | | 68 | | /// The Y component of the vector. |
| | | 69 | | /// </summary> |
| | | 70 | | [JsonInclude] |
| | | 71 | | [MemoryPackOrder(1)] |
| | | 72 | | public Fixed64 y; |
| | | 73 | | |
| | | 74 | | /// <summary> |
| | | 75 | | /// The Z component of the vector. |
| | | 76 | | /// </summary> |
| | | 77 | | [JsonInclude] |
| | | 78 | | [MemoryPackOrder(2)] |
| | | 79 | | public Fixed64 z; |
| | | 80 | | |
| | | 81 | | /// <summary> |
| | | 82 | | /// The W component of the vector. |
| | | 83 | | /// </summary> |
| | | 84 | | [JsonInclude] |
| | | 85 | | [MemoryPackOrder(3)] |
| | | 86 | | public Fixed64 w; |
| | | 87 | | |
| | | 88 | | #endregion |
| | | 89 | | |
| | | 90 | | #region Constructors |
| | | 91 | | |
| | | 92 | | /// <summary> |
| | | 93 | | /// Initializes a new Vector4d using integer component values. |
| | | 94 | | /// </summary> |
| | | 95 | | public Vector4d(int xInt, int yInt, int zInt, int wInt) |
| | 393 | 96 | | : this((Fixed64)xInt, (Fixed64)yInt, (Fixed64)zInt, (Fixed64)wInt) { } |
| | | 97 | | |
| | | 98 | | /// <summary> |
| | | 99 | | /// Initializes a new Vector4d using double component values. |
| | | 100 | | /// </summary> |
| | | 101 | | public Vector4d(double xDoub, double yDoub, double zDoub, double wDoub) |
| | 18 | 102 | | : this((Fixed64)xDoub, (Fixed64)yDoub, (Fixed64)zDoub, (Fixed64)wDoub) { } |
| | | 103 | | |
| | | 104 | | /// <summary> |
| | | 105 | | /// Initializes a new Vector4d using the specified components. |
| | | 106 | | /// </summary> |
| | | 107 | | [JsonConstructor] |
| | | 108 | | public Vector4d(Fixed64 x, Fixed64 y, Fixed64 z, Fixed64 w) |
| | 200 | 109 | | { |
| | 200 | 110 | | this.x = x; |
| | 200 | 111 | | this.y = y; |
| | 200 | 112 | | this.z = z; |
| | 200 | 113 | | this.w = w; |
| | 200 | 114 | | } |
| | | 115 | | |
| | | 116 | | /// <summary> |
| | | 117 | | /// Initializes a new Vector4d with all components set to the same value. |
| | | 118 | | /// </summary> |
| | | 119 | | public Vector4d(Fixed64 value) |
| | 3 | 120 | | : this(value, value, value, value) { } |
| | | 121 | | |
| | | 122 | | /// <summary> |
| | | 123 | | /// Initializes a new Vector4d from a Vector2d plus Z and W components. |
| | | 124 | | /// </summary> |
| | | 125 | | public Vector4d(Vector2d value, Fixed64 z, Fixed64 w) |
| | 3 | 126 | | : this(value.x, value.y, z, w) { } |
| | | 127 | | |
| | | 128 | | /// <summary> |
| | | 129 | | /// Initializes a new Vector4d from a Vector3d plus a W component. |
| | | 130 | | /// </summary> |
| | | 131 | | public Vector4d(Vector3d value, Fixed64 w) |
| | 3 | 132 | | : this(value.x, value.y, value.z, w) { } |
| | | 133 | | |
| | | 134 | | #endregion |
| | | 135 | | |
| | | 136 | | #region Properties |
| | | 137 | | |
| | | 138 | | /// <inheritdoc cref="GetNormalized(Vector4d)"/> |
| | | 139 | | [JsonIgnore] |
| | | 140 | | [MemoryPackIgnore] |
| | | 141 | | public readonly Vector4d Normal |
| | | 142 | | { |
| | | 143 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | 1 | 144 | | get => GetNormalized(this); |
| | | 145 | | } |
| | | 146 | | |
| | | 147 | | /// <summary> |
| | | 148 | | /// Returns the actual length of this vector. |
| | | 149 | | /// </summary> |
| | | 150 | | [JsonIgnore] |
| | | 151 | | [MemoryPackIgnore] |
| | | 152 | | public readonly Fixed64 Magnitude |
| | | 153 | | { |
| | | 154 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | 3 | 155 | | get => GetMagnitude(this); |
| | | 156 | | } |
| | | 157 | | |
| | | 158 | | /// <summary> |
| | | 159 | | /// Returns the square magnitude of the vector. |
| | | 160 | | /// </summary> |
| | | 161 | | [JsonIgnore] |
| | | 162 | | [MemoryPackIgnore] |
| | | 163 | | public readonly Fixed64 SqrMagnitude |
| | | 164 | | { |
| | | 165 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | 5 | 166 | | get => (x * x) + (y * y) + (z * z) + (w * w); |
| | | 167 | | } |
| | | 168 | | |
| | | 169 | | /// <summary> |
| | | 170 | | /// Returns a long hash of the vector based on its component values. |
| | | 171 | | /// </summary> |
| | | 172 | | [JsonIgnore] |
| | | 173 | | [MemoryPackIgnore] |
| | | 174 | | public readonly long LongStateHash |
| | | 175 | | { |
| | | 176 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 177 | | get |
| | 6 | 178 | | { |
| | | 179 | | unchecked |
| | 6 | 180 | | { |
| | 6 | 181 | | return (x.m_rawValue * 31) + (y.m_rawValue * 7) + (z.m_rawValue * 11) + (w.m_rawValue * 17); |
| | | 182 | | } |
| | 6 | 183 | | } |
| | | 184 | | } |
| | | 185 | | |
| | | 186 | | /// <summary> |
| | | 187 | | /// Returns a hash of the vector based on its state. |
| | | 188 | | /// </summary> |
| | | 189 | | [JsonIgnore] |
| | | 190 | | [MemoryPackIgnore] |
| | | 191 | | public readonly int StateHash |
| | | 192 | | { |
| | | 193 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | 4 | 194 | | get => unchecked((int)(LongStateHash % int.MaxValue)); |
| | | 195 | | } |
| | | 196 | | |
| | | 197 | | /// <summary> |
| | | 198 | | /// Are all components of this vector equal to zero? |
| | | 199 | | /// </summary> |
| | | 200 | | [JsonIgnore] |
| | | 201 | | [MemoryPackIgnore] |
| | | 202 | | public readonly bool IsZero |
| | | 203 | | { |
| | | 204 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | 5 | 205 | | get => Equals(Zero); |
| | | 206 | | } |
| | | 207 | | |
| | | 208 | | /// <summary> |
| | | 209 | | /// Gets or sets the vector component at the specified index. |
| | | 210 | | /// </summary> |
| | | 211 | | [JsonIgnore] |
| | | 212 | | [MemoryPackIgnore] |
| | | 213 | | public Fixed64 this[int index] |
| | | 214 | | { |
| | | 215 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 216 | | readonly get |
| | 10 | 217 | | { |
| | 10 | 218 | | return index switch |
| | 10 | 219 | | { |
| | 2 | 220 | | 0 => x, |
| | 2 | 221 | | 1 => y, |
| | 2 | 222 | | 2 => z, |
| | 2 | 223 | | 3 => w, |
| | 2 | 224 | | _ => throw new IndexOutOfRangeException("Invalid Vector4d index!"), |
| | 10 | 225 | | }; |
| | 8 | 226 | | } |
| | | 227 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 228 | | set |
| | 34 | 229 | | { |
| | 34 | 230 | | switch (index) |
| | | 231 | | { |
| | | 232 | | case 0: |
| | 8 | 233 | | x = value; |
| | 8 | 234 | | break; |
| | | 235 | | case 1: |
| | 8 | 236 | | y = value; |
| | 8 | 237 | | break; |
| | | 238 | | case 2: |
| | 8 | 239 | | z = value; |
| | 8 | 240 | | break; |
| | | 241 | | case 3: |
| | 8 | 242 | | w = value; |
| | 8 | 243 | | break; |
| | | 244 | | default: |
| | 2 | 245 | | throw new IndexOutOfRangeException("Invalid Vector4d index!"); |
| | | 246 | | } |
| | 32 | 247 | | } |
| | | 248 | | } |
| | | 249 | | |
| | | 250 | | #endregion |
| | | 251 | | |
| | | 252 | | #region Instance Methods |
| | | 253 | | |
| | | 254 | | /// <summary> |
| | | 255 | | /// Sets the vector components in place and returns the modified vector. |
| | | 256 | | /// </summary> |
| | | 257 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 258 | | public Vector4d Set(Fixed64 newX, Fixed64 newY, Fixed64 newZ, Fixed64 newW) |
| | 1 | 259 | | { |
| | 1 | 260 | | x = newX; |
| | 1 | 261 | | y = newY; |
| | 1 | 262 | | z = newZ; |
| | 1 | 263 | | w = newW; |
| | 1 | 264 | | return this; |
| | 1 | 265 | | } |
| | | 266 | | |
| | | 267 | | /// <summary> |
| | | 268 | | /// Adds the specified scalar to all components in place. |
| | | 269 | | /// </summary> |
| | | 270 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 271 | | public Vector4d AddInPlace(Fixed64 amount) |
| | 1 | 272 | | { |
| | 1 | 273 | | x += amount; |
| | 1 | 274 | | y += amount; |
| | 1 | 275 | | z += amount; |
| | 1 | 276 | | w += amount; |
| | 1 | 277 | | return this; |
| | 1 | 278 | | } |
| | | 279 | | |
| | | 280 | | /// <summary> |
| | | 281 | | /// Adds the specified component values in place. |
| | | 282 | | /// </summary> |
| | | 283 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 284 | | public Vector4d AddInPlace(Fixed64 xAmount, Fixed64 yAmount, Fixed64 zAmount, Fixed64 wAmount) |
| | 1 | 285 | | { |
| | 1 | 286 | | x += xAmount; |
| | 1 | 287 | | y += yAmount; |
| | 1 | 288 | | z += zAmount; |
| | 1 | 289 | | w += wAmount; |
| | 1 | 290 | | return this; |
| | 1 | 291 | | } |
| | | 292 | | |
| | | 293 | | /// <summary> |
| | | 294 | | /// Adds another vector in place. |
| | | 295 | | /// </summary> |
| | | 296 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 297 | | public Vector4d AddInPlace(Vector4d other) |
| | 1 | 298 | | { |
| | 1 | 299 | | x += other.x; |
| | 1 | 300 | | y += other.y; |
| | 1 | 301 | | z += other.z; |
| | 1 | 302 | | w += other.w; |
| | 1 | 303 | | return this; |
| | 1 | 304 | | } |
| | | 305 | | |
| | | 306 | | /// <summary> |
| | | 307 | | /// Subtracts the specified scalar from all components in place. |
| | | 308 | | /// </summary> |
| | | 309 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 310 | | public Vector4d SubtractInPlace(Fixed64 amount) |
| | 1 | 311 | | { |
| | 1 | 312 | | x -= amount; |
| | 1 | 313 | | y -= amount; |
| | 1 | 314 | | z -= amount; |
| | 1 | 315 | | w -= amount; |
| | 1 | 316 | | return this; |
| | 1 | 317 | | } |
| | | 318 | | |
| | | 319 | | /// <summary> |
| | | 320 | | /// Subtracts the specified component values in place. |
| | | 321 | | /// </summary> |
| | | 322 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 323 | | public Vector4d SubtractInPlace(Fixed64 xAmount, Fixed64 yAmount, Fixed64 zAmount, Fixed64 wAmount) |
| | 1 | 324 | | { |
| | 1 | 325 | | x -= xAmount; |
| | 1 | 326 | | y -= yAmount; |
| | 1 | 327 | | z -= zAmount; |
| | 1 | 328 | | w -= wAmount; |
| | 1 | 329 | | return this; |
| | 1 | 330 | | } |
| | | 331 | | |
| | | 332 | | /// <summary> |
| | | 333 | | /// Subtracts another vector in place. |
| | | 334 | | /// </summary> |
| | | 335 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 336 | | public Vector4d SubtractInPlace(Vector4d other) |
| | 1 | 337 | | { |
| | 1 | 338 | | x -= other.x; |
| | 1 | 339 | | y -= other.y; |
| | 1 | 340 | | z -= other.z; |
| | 1 | 341 | | w -= other.w; |
| | 1 | 342 | | return this; |
| | 1 | 343 | | } |
| | | 344 | | |
| | | 345 | | /// <summary> |
| | | 346 | | /// Scales all components in place. |
| | | 347 | | /// </summary> |
| | | 348 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 349 | | public Vector4d ScaleInPlace(Fixed64 scaleFactor) |
| | 1 | 350 | | { |
| | 1 | 351 | | x *= scaleFactor; |
| | 1 | 352 | | y *= scaleFactor; |
| | 1 | 353 | | z *= scaleFactor; |
| | 1 | 354 | | w *= scaleFactor; |
| | 1 | 355 | | return this; |
| | 1 | 356 | | } |
| | | 357 | | |
| | | 358 | | /// <summary> |
| | | 359 | | /// Scales all components by another vector in place. |
| | | 360 | | /// </summary> |
| | | 361 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 362 | | public Vector4d ScaleInPlace(Vector4d scale) |
| | 1 | 363 | | { |
| | 1 | 364 | | x *= scale.x; |
| | 1 | 365 | | y *= scale.y; |
| | 1 | 366 | | z *= scale.z; |
| | 1 | 367 | | w *= scale.w; |
| | 1 | 368 | | return this; |
| | 1 | 369 | | } |
| | | 370 | | |
| | | 371 | | /// <summary> |
| | | 372 | | /// Normalizes this vector in place. |
| | | 373 | | /// </summary> |
| | | 374 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 375 | | public Vector4d Normalize() |
| | 1 | 376 | | { |
| | 1 | 377 | | return this = GetNormalized(this); |
| | 1 | 378 | | } |
| | | 379 | | |
| | | 380 | | /// <summary> |
| | | 381 | | /// Normalizes this vector in place and returns its original magnitude. |
| | | 382 | | /// </summary> |
| | | 383 | | public Vector4d Normalize(out Fixed64 mag) |
| | 3 | 384 | | { |
| | 3 | 385 | | mag = GetMagnitude(this); |
| | | 386 | | |
| | 3 | 387 | | if (mag == Fixed64.Zero) |
| | 1 | 388 | | return this = Zero; |
| | | 389 | | |
| | 2 | 390 | | if (FixedMath.Abs(mag - Fixed64.One) <= Fixed64.Epsilon) |
| | 1 | 391 | | return this; |
| | | 392 | | |
| | 1 | 393 | | return this = new Vector4d(x / mag, y / mag, z / mag, w / mag); |
| | 3 | 394 | | } |
| | | 395 | | |
| | | 396 | | /// <summary> |
| | | 397 | | /// Determines whether this vector is normalized. |
| | | 398 | | /// </summary> |
| | | 399 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 400 | | public readonly bool IsNormalized() |
| | 3 | 401 | | { |
| | 3 | 402 | | return !IsZero && FixedMath.Abs(SqrMagnitude - Fixed64.One) <= Fixed64.Epsilon; |
| | 3 | 403 | | } |
| | | 404 | | |
| | | 405 | | /// <summary> |
| | | 406 | | /// Determines whether all components are greater than Fixed64.Epsilon. |
| | | 407 | | /// </summary> |
| | | 408 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 409 | | public readonly bool AllComponentsGreaterThanEpsilon() |
| | 5 | 410 | | { |
| | 5 | 411 | | return x > Fixed64.Epsilon && y > Fixed64.Epsilon && z > Fixed64.Epsilon && w > Fixed64.Epsilon; |
| | 5 | 412 | | } |
| | | 413 | | |
| | | 414 | | /// <summary> |
| | | 415 | | /// Snaps components with absolute values below the threshold to zero. |
| | | 416 | | /// </summary> |
| | | 417 | | public readonly Vector4d SnapSmallComponentsToZero(Fixed64? threshold = null) |
| | 3 | 418 | | { |
| | 3 | 419 | | Fixed64 t = threshold ?? Fixed64.Epsilon; |
| | 3 | 420 | | return new Vector4d( |
| | 3 | 421 | | FixedMath.Abs(x) < t ? Fixed64.Zero : x, |
| | 3 | 422 | | FixedMath.Abs(y) < t ? Fixed64.Zero : y, |
| | 3 | 423 | | FixedMath.Abs(z) < t ? Fixed64.Zero : z, |
| | 3 | 424 | | FixedMath.Abs(w) < t ? Fixed64.Zero : w); |
| | 3 | 425 | | } |
| | | 426 | | |
| | | 427 | | /// <summary> |
| | | 428 | | /// Calculates the distance to another vector. |
| | | 429 | | /// </summary> |
| | | 430 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 431 | | public readonly Fixed64 Distance(Fixed64 otherX, Fixed64 otherY, Fixed64 otherZ, Fixed64 otherW) |
| | 3 | 432 | | { |
| | 3 | 433 | | return FixedMath.Sqrt(SqrDistance(otherX, otherY, otherZ, otherW)); |
| | 3 | 434 | | } |
| | | 435 | | |
| | | 436 | | /// <summary> |
| | | 437 | | /// Calculates the distance to another vector. |
| | | 438 | | /// </summary> |
| | | 439 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 440 | | public readonly Fixed64 Distance(Vector4d other) |
| | 1 | 441 | | { |
| | 1 | 442 | | return Distance(other.x, other.y, other.z, other.w); |
| | 1 | 443 | | } |
| | | 444 | | |
| | | 445 | | /// <summary> |
| | | 446 | | /// Calculates the squared distance to another vector. |
| | | 447 | | /// </summary> |
| | | 448 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 449 | | public readonly Fixed64 SqrDistance(Fixed64 otherX, Fixed64 otherY, Fixed64 otherZ, Fixed64 otherW) |
| | 5 | 450 | | { |
| | 5 | 451 | | Fixed64 dx = otherX - x; |
| | 5 | 452 | | Fixed64 dy = otherY - y; |
| | 5 | 453 | | Fixed64 dz = otherZ - z; |
| | 5 | 454 | | Fixed64 dw = otherW - w; |
| | 5 | 455 | | return (dx * dx) + (dy * dy) + (dz * dz) + (dw * dw); |
| | 5 | 456 | | } |
| | | 457 | | |
| | | 458 | | /// <summary> |
| | | 459 | | /// Calculates the squared distance to another vector. |
| | | 460 | | /// </summary> |
| | | 461 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 462 | | public readonly Fixed64 SqrDistance(Vector4d other) |
| | 1 | 463 | | { |
| | 1 | 464 | | return SqrDistance(other.x, other.y, other.z, other.w); |
| | 1 | 465 | | } |
| | | 466 | | |
| | | 467 | | /// <summary> |
| | | 468 | | /// Calculates the dot product with another vector. |
| | | 469 | | /// </summary> |
| | | 470 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 471 | | public readonly Fixed64 Dot(Fixed64 otherX, Fixed64 otherY, Fixed64 otherZ, Fixed64 otherW) |
| | 2 | 472 | | { |
| | 2 | 473 | | return (x * otherX) + (y * otherY) + (z * otherZ) + (w * otherW); |
| | 2 | 474 | | } |
| | | 475 | | |
| | | 476 | | /// <summary> |
| | | 477 | | /// Calculates the dot product with another vector. |
| | | 478 | | /// </summary> |
| | | 479 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 480 | | public readonly Fixed64 Dot(Vector4d other) |
| | 1 | 481 | | { |
| | 1 | 482 | | return Dot(other.x, other.y, other.z, other.w); |
| | 1 | 483 | | } |
| | | 484 | | |
| | | 485 | | /// <summary> |
| | | 486 | | /// Converts this vector to Vector3d by dropping the W component. |
| | | 487 | | /// </summary> |
| | | 488 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 489 | | public readonly Vector3d ToVector3d() |
| | 1 | 490 | | { |
| | 1 | 491 | | return new Vector3d(x, y, z); |
| | 1 | 492 | | } |
| | | 493 | | |
| | | 494 | | #endregion |
| | | 495 | | |
| | | 496 | | #region Static Methods |
| | | 497 | | |
| | | 498 | | /// <summary> |
| | | 499 | | /// Linearly interpolates between two vectors, clamping the interpolation amount to [0, 1]. |
| | | 500 | | /// </summary> |
| | | 501 | | public static Vector4d Lerp(Vector4d a, Vector4d b, Fixed64 amount) |
| | 1 | 502 | | { |
| | 1 | 503 | | amount = FixedMath.Clamp01(amount); |
| | 1 | 504 | | return UnclampedLerp(a, b, amount); |
| | 1 | 505 | | } |
| | | 506 | | |
| | | 507 | | /// <summary> |
| | | 508 | | /// Linearly interpolates between two vectors without clamping the interpolation amount. |
| | | 509 | | /// </summary> |
| | | 510 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 511 | | public static Vector4d UnclampedLerp(Vector4d a, Vector4d b, Fixed64 t) |
| | 2 | 512 | | { |
| | 2 | 513 | | return new Vector4d( |
| | 2 | 514 | | a.x + ((b.x - a.x) * t), |
| | 2 | 515 | | a.y + ((b.y - a.y) * t), |
| | 2 | 516 | | a.z + ((b.z - a.z) * t), |
| | 2 | 517 | | a.w + ((b.w - a.w) * t)); |
| | 2 | 518 | | } |
| | | 519 | | |
| | | 520 | | /// <summary> |
| | | 521 | | /// Normalizes the given vector, returning a unit vector with the same direction. |
| | | 522 | | /// </summary> |
| | | 523 | | public static Vector4d GetNormalized(Vector4d value) |
| | 4 | 524 | | { |
| | 4 | 525 | | Fixed64 mag = GetMagnitude(value); |
| | | 526 | | |
| | 4 | 527 | | if (mag == Fixed64.Zero) |
| | 2 | 528 | | return Zero; |
| | | 529 | | |
| | 2 | 530 | | if (FixedMath.Abs(mag - Fixed64.One) <= Fixed64.Epsilon) |
| | 1 | 531 | | return value; |
| | | 532 | | |
| | 1 | 533 | | return new Vector4d(value.x / mag, value.y / mag, value.z / mag, value.w / mag); |
| | 4 | 534 | | } |
| | | 535 | | |
| | | 536 | | /// <summary> |
| | | 537 | | /// Returns the magnitude of the given vector. |
| | | 538 | | /// </summary> |
| | | 539 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 540 | | public static Fixed64 GetMagnitude(Vector4d vector) |
| | 10 | 541 | | { |
| | 10 | 542 | | Fixed64 mag = (vector.x * vector.x) + (vector.y * vector.y) + (vector.z * vector.z) + (vector.w * vector.w); |
| | | 543 | | |
| | 10 | 544 | | if (FixedMath.Abs(mag - Fixed64.One) <= Fixed64.Epsilon) |
| | 4 | 545 | | return Fixed64.One; |
| | | 546 | | |
| | 6 | 547 | | return mag != Fixed64.Zero ? FixedMath.Sqrt(mag) : Fixed64.Zero; |
| | 10 | 548 | | } |
| | | 549 | | |
| | | 550 | | /// <summary> |
| | | 551 | | /// Returns a new vector containing the absolute value of each component. |
| | | 552 | | /// </summary> |
| | | 553 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 554 | | public static Vector4d Abs(Vector4d value) |
| | 2 | 555 | | { |
| | 2 | 556 | | return new Vector4d(FixedMath.Abs(value.x), FixedMath.Abs(value.y), FixedMath.Abs(value.z), FixedMath.Abs(value. |
| | 2 | 557 | | } |
| | | 558 | | |
| | | 559 | | /// <summary> |
| | | 560 | | /// Returns a new vector containing the sign of each component. |
| | | 561 | | /// </summary> |
| | | 562 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 563 | | public static Vector4d Sign(Vector4d value) |
| | 2 | 564 | | { |
| | 2 | 565 | | return new Vector4d(value.x.Sign(), value.y.Sign(), value.z.Sign(), value.w.Sign()); |
| | 2 | 566 | | } |
| | | 567 | | |
| | | 568 | | /// <summary> |
| | | 569 | | /// Clamps each component of the given vector within the specified min and max bounds. |
| | | 570 | | /// </summary> |
| | | 571 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 572 | | public static Vector4d Clamp(Vector4d value, Vector4d min, Vector4d max) |
| | 1 | 573 | | { |
| | 1 | 574 | | return new Vector4d( |
| | 1 | 575 | | FixedMath.Clamp(value.x, min.x, max.x), |
| | 1 | 576 | | FixedMath.Clamp(value.y, min.y, max.y), |
| | 1 | 577 | | FixedMath.Clamp(value.z, min.z, max.z), |
| | 1 | 578 | | FixedMath.Clamp(value.w, min.w, max.w)); |
| | 1 | 579 | | } |
| | | 580 | | |
| | | 581 | | /// <summary> |
| | | 582 | | /// Computes the midpoint between two vectors. |
| | | 583 | | /// </summary> |
| | | 584 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 585 | | public static Vector4d Midpoint(Vector4d v1, Vector4d v2) |
| | 1 | 586 | | { |
| | 1 | 587 | | return new Vector4d( |
| | 1 | 588 | | (v1.x + v2.x) * Fixed64.Half, |
| | 1 | 589 | | (v1.y + v2.y) * Fixed64.Half, |
| | 1 | 590 | | (v1.z + v2.z) * Fixed64.Half, |
| | 1 | 591 | | (v1.w + v2.w) * Fixed64.Half); |
| | 1 | 592 | | } |
| | | 593 | | |
| | | 594 | | /// <inheritdoc cref="Distance(Fixed64, Fixed64, Fixed64, Fixed64)" /> |
| | | 595 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 596 | | public static Fixed64 Distance(Vector4d start, Vector4d end) |
| | 1 | 597 | | { |
| | 1 | 598 | | return start.Distance(end.x, end.y, end.z, end.w); |
| | 1 | 599 | | } |
| | | 600 | | |
| | | 601 | | /// <inheritdoc cref="SqrDistance(Fixed64, Fixed64, Fixed64, Fixed64)" /> |
| | | 602 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 603 | | public static Fixed64 SqrDistance(Vector4d start, Vector4d end) |
| | 1 | 604 | | { |
| | 1 | 605 | | return start.SqrDistance(end.x, end.y, end.z, end.w); |
| | 1 | 606 | | } |
| | | 607 | | |
| | | 608 | | /// <summary> |
| | | 609 | | /// Calculates the dot product of two vectors. |
| | | 610 | | /// </summary> |
| | | 611 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 612 | | public static Fixed64 Dot(Vector4d lhs, Vector4d rhs) |
| | 1 | 613 | | { |
| | 1 | 614 | | return lhs.Dot(rhs.x, rhs.y, rhs.z, rhs.w); |
| | 1 | 615 | | } |
| | | 616 | | |
| | | 617 | | /// <summary> |
| | | 618 | | /// Multiplies two vectors component-wise. |
| | | 619 | | /// </summary> |
| | | 620 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 621 | | public static Vector4d Scale(Vector4d a, Vector4d b) |
| | 2 | 622 | | { |
| | 2 | 623 | | return new Vector4d(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); |
| | 2 | 624 | | } |
| | | 625 | | |
| | | 626 | | /// <summary> |
| | | 627 | | /// Returns a vector whose elements are the maximum of each pair of elements. |
| | | 628 | | /// </summary> |
| | | 629 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 630 | | public static Vector4d Max(Vector4d value1, Vector4d value2) |
| | 1 | 631 | | { |
| | 1 | 632 | | return new Vector4d( |
| | 1 | 633 | | FixedMath.Max(value1.x, value2.x), |
| | 1 | 634 | | FixedMath.Max(value1.y, value2.y), |
| | 1 | 635 | | FixedMath.Max(value1.z, value2.z), |
| | 1 | 636 | | FixedMath.Max(value1.w, value2.w)); |
| | 1 | 637 | | } |
| | | 638 | | |
| | | 639 | | /// <summary> |
| | | 640 | | /// Returns a vector whose elements are the minimum of each pair of elements. |
| | | 641 | | /// </summary> |
| | | 642 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 643 | | public static Vector4d Min(Vector4d value1, Vector4d value2) |
| | 1 | 644 | | { |
| | 1 | 645 | | return new Vector4d( |
| | 1 | 646 | | FixedMath.Min(value1.x, value2.x), |
| | 1 | 647 | | FixedMath.Min(value1.y, value2.y), |
| | 1 | 648 | | FixedMath.Min(value1.z, value2.z), |
| | 1 | 649 | | FixedMath.Min(value1.w, value2.w)); |
| | 1 | 650 | | } |
| | | 651 | | |
| | | 652 | | /// <summary> |
| | | 653 | | /// Transforms a 4D vector by a 4x4 matrix. |
| | | 654 | | /// </summary> |
| | | 655 | | /// <remarks> |
| | | 656 | | /// This follows the same storage convention as <see cref="Fixed4x4.TransformPoint(Fixed4x4, Vector3d)"/>, |
| | | 657 | | /// preserving the computed W component instead of performing perspective division. |
| | | 658 | | /// </remarks> |
| | | 659 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 660 | | public static Vector4d Transform(Fixed4x4 matrix, Vector4d vector) |
| | 8 | 661 | | { |
| | 8 | 662 | | return new Vector4d( |
| | 8 | 663 | | matrix.m00 * vector.x + matrix.m01 * vector.y + matrix.m02 * vector.z + matrix.m30 * vector.w, |
| | 8 | 664 | | matrix.m10 * vector.x + matrix.m11 * vector.y + matrix.m12 * vector.z + matrix.m31 * vector.w, |
| | 8 | 665 | | matrix.m20 * vector.x + matrix.m21 * vector.y + matrix.m22 * vector.z + matrix.m32 * vector.w, |
| | 8 | 666 | | matrix.m03 * vector.x + matrix.m13 * vector.y + matrix.m23 * vector.z + matrix.m33 * vector.w); |
| | 8 | 667 | | } |
| | | 668 | | |
| | | 669 | | #endregion |
| | | 670 | | |
| | | 671 | | #region Operators |
| | | 672 | | |
| | | 673 | | /// <summary> |
| | | 674 | | /// Adds two vectors component-wise. |
| | | 675 | | /// </summary> |
| | | 676 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 677 | | public static Vector4d operator +(Vector4d v1, Vector4d v2) |
| | 1 | 678 | | { |
| | 1 | 679 | | return new Vector4d(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w); |
| | 1 | 680 | | } |
| | | 681 | | |
| | | 682 | | /// <summary> |
| | | 683 | | /// Adds a scalar to each component. |
| | | 684 | | /// </summary> |
| | | 685 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 686 | | public static Vector4d operator +(Vector4d v1, Fixed64 mag) |
| | 2 | 687 | | { |
| | 2 | 688 | | return new Vector4d(v1.x + mag, v1.y + mag, v1.z + mag, v1.w + mag); |
| | 2 | 689 | | } |
| | | 690 | | |
| | | 691 | | /// <inheritdoc cref="operator +(Vector4d, Fixed64)"/> |
| | | 692 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 693 | | public static Vector4d operator +(Fixed64 mag, Vector4d v1) |
| | 1 | 694 | | { |
| | 1 | 695 | | return v1 + mag; |
| | 1 | 696 | | } |
| | | 697 | | |
| | | 698 | | /// <summary> |
| | | 699 | | /// Adds a tuple to each component. |
| | | 700 | | /// </summary> |
| | | 701 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 702 | | public static Vector4d operator +(Vector4d v1, (int x, int y, int z, int w) v2) |
| | 2 | 703 | | { |
| | 2 | 704 | | return new Vector4d(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w); |
| | 2 | 705 | | } |
| | | 706 | | |
| | | 707 | | /// <summary> |
| | | 708 | | /// Adds a tuple to each component. |
| | | 709 | | /// </summary> |
| | | 710 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 711 | | public static Vector4d operator +((int x, int y, int z, int w) v2, Vector4d v1) |
| | 1 | 712 | | { |
| | 1 | 713 | | return v1 + v2; |
| | 1 | 714 | | } |
| | | 715 | | |
| | | 716 | | /// <summary> |
| | | 717 | | /// Subtracts two vectors component-wise. |
| | | 718 | | /// </summary> |
| | | 719 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 720 | | public static Vector4d operator -(Vector4d v1, Vector4d v2) |
| | 1 | 721 | | { |
| | 1 | 722 | | return new Vector4d(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w); |
| | 1 | 723 | | } |
| | | 724 | | |
| | | 725 | | /// <summary> |
| | | 726 | | /// Subtracts a scalar from each component. |
| | | 727 | | /// </summary> |
| | | 728 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 729 | | public static Vector4d operator -(Vector4d v1, Fixed64 mag) |
| | 1 | 730 | | { |
| | 1 | 731 | | return new Vector4d(v1.x - mag, v1.y - mag, v1.z - mag, v1.w - mag); |
| | 1 | 732 | | } |
| | | 733 | | |
| | | 734 | | /// <inheritdoc cref="operator -(Vector4d, Fixed64)"/> |
| | | 735 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 736 | | public static Vector4d operator -(Fixed64 mag, Vector4d v1) |
| | 1 | 737 | | { |
| | 1 | 738 | | return new Vector4d(mag - v1.x, mag - v1.y, mag - v1.z, mag - v1.w); |
| | 1 | 739 | | } |
| | | 740 | | |
| | | 741 | | /// <summary> |
| | | 742 | | /// Subtracts a tuple from each component. |
| | | 743 | | /// </summary> |
| | | 744 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 745 | | public static Vector4d operator -(Vector4d v1, (int x, int y, int z, int w) v2) |
| | 1 | 746 | | { |
| | 1 | 747 | | return new Vector4d(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w); |
| | 1 | 748 | | } |
| | | 749 | | |
| | | 750 | | /// <summary> |
| | | 751 | | /// Subtracts each vector component from a tuple component. |
| | | 752 | | /// </summary> |
| | | 753 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 754 | | public static Vector4d operator -((int x, int y, int z, int w) v1, Vector4d v2) |
| | 1 | 755 | | { |
| | 1 | 756 | | return new Vector4d(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w); |
| | 1 | 757 | | } |
| | | 758 | | |
| | | 759 | | /// <summary> |
| | | 760 | | /// Negates the vector. |
| | | 761 | | /// </summary> |
| | | 762 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 763 | | public static Vector4d operator -(Vector4d v1) |
| | 1 | 764 | | { |
| | 1 | 765 | | return new Vector4d(-v1.x, -v1.y, -v1.z, -v1.w); |
| | 1 | 766 | | } |
| | | 767 | | |
| | | 768 | | /// <summary> |
| | | 769 | | /// Multiplies each component by a scalar. |
| | | 770 | | /// </summary> |
| | | 771 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 772 | | public static Vector4d operator *(Vector4d v1, Fixed64 mag) |
| | 4 | 773 | | { |
| | 4 | 774 | | return new Vector4d(v1.x * mag, v1.y * mag, v1.z * mag, v1.w * mag); |
| | 4 | 775 | | } |
| | | 776 | | |
| | | 777 | | /// <inheritdoc cref="operator *(Vector4d, Fixed64)"/> |
| | | 778 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 779 | | public static Vector4d operator *(Fixed64 mag, Vector4d v1) |
| | 1 | 780 | | { |
| | 1 | 781 | | return v1 * mag; |
| | 1 | 782 | | } |
| | | 783 | | |
| | | 784 | | /// <summary> |
| | | 785 | | /// Multiplies each component by an integer scalar. |
| | | 786 | | /// </summary> |
| | | 787 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 788 | | public static Vector4d operator *(Vector4d v1, int mag) |
| | 2 | 789 | | { |
| | 2 | 790 | | return v1 * (Fixed64)mag; |
| | 2 | 791 | | } |
| | | 792 | | |
| | | 793 | | /// <inheritdoc cref="operator *(Vector4d, int)"/> |
| | | 794 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 795 | | public static Vector4d operator *(int mag, Vector4d v1) |
| | 1 | 796 | | { |
| | 1 | 797 | | return v1 * mag; |
| | 1 | 798 | | } |
| | | 799 | | |
| | | 800 | | /// <summary> |
| | | 801 | | /// Multiplies two vectors component-wise. |
| | | 802 | | /// </summary> |
| | | 803 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 804 | | public static Vector4d operator *(Vector4d v1, Vector4d v2) |
| | 1 | 805 | | { |
| | 1 | 806 | | return Scale(v1, v2); |
| | 1 | 807 | | } |
| | | 808 | | |
| | | 809 | | /// <summary> |
| | | 810 | | /// Transforms a vector by a 4x4 matrix. |
| | | 811 | | /// </summary> |
| | | 812 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 813 | | public static Vector4d operator *(Fixed4x4 matrix, Vector4d vector) |
| | 5 | 814 | | { |
| | 5 | 815 | | return Transform(matrix, vector); |
| | 5 | 816 | | } |
| | | 817 | | |
| | | 818 | | /// <inheritdoc cref="operator *(Fixed4x4, Vector4d)"/> |
| | | 819 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 820 | | public static Vector4d operator *(Vector4d vector, Fixed4x4 matrix) |
| | 1 | 821 | | { |
| | 1 | 822 | | return matrix * vector; |
| | 1 | 823 | | } |
| | | 824 | | |
| | | 825 | | /// <summary> |
| | | 826 | | /// Divides each component by a scalar. |
| | | 827 | | /// </summary> |
| | | 828 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 829 | | public static Vector4d operator /(Vector4d v1, Fixed64 div) |
| | 2 | 830 | | { |
| | 2 | 831 | | return new Vector4d(v1.x / div, v1.y / div, v1.z / div, v1.w / div); |
| | 2 | 832 | | } |
| | | 833 | | |
| | | 834 | | /// <summary> |
| | | 835 | | /// Divides each component by another vector's corresponding component. |
| | | 836 | | /// </summary> |
| | | 837 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 838 | | public static Vector4d operator /(Vector4d v1, Vector4d v2) |
| | 1 | 839 | | { |
| | 1 | 840 | | return new Vector4d(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w); |
| | 1 | 841 | | } |
| | | 842 | | |
| | | 843 | | /// <summary> |
| | | 844 | | /// Divides each component by an integer scalar. |
| | | 845 | | /// </summary> |
| | | 846 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 847 | | public static Vector4d operator /(Vector4d v1, int div) |
| | 1 | 848 | | { |
| | 1 | 849 | | return v1 / (Fixed64)div; |
| | 1 | 850 | | } |
| | | 851 | | |
| | | 852 | | /// <summary> |
| | | 853 | | /// Compares two vectors for equality. |
| | | 854 | | /// </summary> |
| | | 855 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | 1 | 856 | | public static bool operator ==(Vector4d left, Vector4d right) => left.Equals(right); |
| | | 857 | | |
| | | 858 | | /// <summary> |
| | | 859 | | /// Compares two vectors for inequality. |
| | | 860 | | /// </summary> |
| | | 861 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | 1 | 862 | | public static bool operator !=(Vector4d left, Vector4d right) => !left.Equals(right); |
| | | 863 | | |
| | | 864 | | /// <summary> |
| | | 865 | | /// Returns true when every component in the left vector is greater than the corresponding component in the right ve |
| | | 866 | | /// </summary> |
| | | 867 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 868 | | public static bool operator >(Vector4d left, Vector4d right) |
| | 5 | 869 | | { |
| | 5 | 870 | | return left.x > right.x && left.y > right.y && left.z > right.z && left.w > right.w; |
| | 5 | 871 | | } |
| | | 872 | | |
| | | 873 | | /// <summary> |
| | | 874 | | /// Returns true when every component in the left vector is less than the corresponding component in the right vecto |
| | | 875 | | /// </summary> |
| | | 876 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 877 | | public static bool operator <(Vector4d left, Vector4d right) |
| | 5 | 878 | | { |
| | 5 | 879 | | return left.x < right.x && left.y < right.y && left.z < right.z && left.w < right.w; |
| | 5 | 880 | | } |
| | | 881 | | |
| | | 882 | | /// <summary> |
| | | 883 | | /// Returns true when every component in the left vector is greater than or equal to the corresponding component in |
| | | 884 | | /// </summary> |
| | | 885 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 886 | | public static bool operator >=(Vector4d left, Vector4d right) |
| | 6 | 887 | | { |
| | 6 | 888 | | return left.x >= right.x && left.y >= right.y && left.z >= right.z && left.w >= right.w; |
| | 6 | 889 | | } |
| | | 890 | | |
| | | 891 | | /// <summary> |
| | | 892 | | /// Returns true when every component in the left vector is less than or equal to the corresponding component in the |
| | | 893 | | /// </summary> |
| | | 894 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 895 | | public static bool operator <=(Vector4d left, Vector4d right) |
| | 6 | 896 | | { |
| | 6 | 897 | | return left.x <= right.x && left.y <= right.y && left.z <= right.z && left.w <= right.w; |
| | 6 | 898 | | } |
| | | 899 | | |
| | | 900 | | #endregion |
| | | 901 | | |
| | | 902 | | #region Conversion and Formatting |
| | | 903 | | |
| | | 904 | | /// <summary> |
| | | 905 | | /// Returns a string representation of this vector. |
| | | 906 | | /// </summary> |
| | | 907 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 908 | | public override readonly string ToString() |
| | 1 | 909 | | { |
| | 1 | 910 | | return string.Format( |
| | 1 | 911 | | "({0}, {1}, {2}, {3})", |
| | 1 | 912 | | x.ToFormattedDouble(), |
| | 1 | 913 | | y.ToFormattedDouble(), |
| | 1 | 914 | | z.ToFormattedDouble(), |
| | 1 | 915 | | w.ToFormattedDouble()); |
| | 1 | 916 | | } |
| | | 917 | | |
| | | 918 | | /// <summary> |
| | | 919 | | /// Deconstructs the vector into single-precision floating-point values. |
| | | 920 | | /// </summary> |
| | | 921 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 922 | | public readonly void Deconstruct(out float x, out float y, out float z, out float w) |
| | 1 | 923 | | { |
| | 1 | 924 | | x = this.x.ToPreciseFloat(); |
| | 1 | 925 | | y = this.y.ToPreciseFloat(); |
| | 1 | 926 | | z = this.z.ToPreciseFloat(); |
| | 1 | 927 | | w = this.w.ToPreciseFloat(); |
| | 1 | 928 | | } |
| | | 929 | | |
| | | 930 | | /// <summary> |
| | | 931 | | /// Deconstructs the vector into rounded integer values. |
| | | 932 | | /// </summary> |
| | | 933 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 934 | | public readonly void Deconstruct(out int x, out int y, out int z, out int w) |
| | 1 | 935 | | { |
| | 1 | 936 | | x = this.x.RoundToInt(); |
| | 1 | 937 | | y = this.y.RoundToInt(); |
| | 1 | 938 | | z = this.z.RoundToInt(); |
| | 1 | 939 | | w = this.w.RoundToInt(); |
| | 1 | 940 | | } |
| | | 941 | | |
| | | 942 | | #endregion |
| | | 943 | | |
| | | 944 | | #region Equality and HashCode Overrides |
| | | 945 | | |
| | | 946 | | /// <inheritdoc/> |
| | | 947 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | 2 | 948 | | public override readonly bool Equals(object? obj) => obj is Vector4d other && Equals(other); |
| | | 949 | | |
| | | 950 | | /// <inheritdoc/> |
| | | 951 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 952 | | public readonly bool Equals(Vector4d other) |
| | 78 | 953 | | { |
| | 78 | 954 | | return other.x == x && other.y == y && other.z == z && other.w == w; |
| | 78 | 955 | | } |
| | | 956 | | |
| | | 957 | | /// <inheritdoc/> |
| | 1 | 958 | | public readonly bool Equals(Vector4d x, Vector4d y) => x.Equals(y); |
| | | 959 | | |
| | | 960 | | /// <inheritdoc/> |
| | | 961 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | 2 | 962 | | public override readonly int GetHashCode() => StateHash; |
| | | 963 | | |
| | | 964 | | /// <inheritdoc/> |
| | 1 | 965 | | public readonly int GetHashCode(Vector4d obj) => obj.GetHashCode(); |
| | | 966 | | |
| | | 967 | | /// <summary> |
| | | 968 | | /// Compares the current Vector4d instance with another Vector4d based on squared magnitude. |
| | | 969 | | /// </summary> |
| | 1 | 970 | | public readonly int CompareTo(Vector4d other) => SqrMagnitude.CompareTo(other.SqrMagnitude); |
| | | 971 | | |
| | | 972 | | #endregion |
| | | 973 | | } |