1 |
using System; |
2 |
|
3 |
namespace Oni |
4 |
{ |
5 |
internal struct Vector4 : IEquatable<Vector4> |
6 |
{ |
7 |
public float X; |
8 |
public float Y; |
9 |
public float Z; |
10 |
public float W; |
11 |
|
12 |
public Vector4(float all) |
13 |
{ |
14 |
X = all; |
15 |
Y = all; |
16 |
Z = all; |
17 |
W = all; |
18 |
} |
19 |
|
20 |
public Vector4(Vector3 v, float w) |
21 |
{ |
22 |
X = v.X; |
23 |
Y = v.Y; |
24 |
Z = v.Z; |
25 |
W = w; |
26 |
} |
27 |
|
28 |
public Vector4(float x, float y, float z, float w) |
29 |
{ |
30 |
X = x; |
31 |
Y = y; |
32 |
Z = z; |
33 |
W = w; |
34 |
} |
35 |
|
36 |
public Vector3 XYZ |
37 |
{ |
38 |
get |
39 |
{ |
40 |
return new Vector3(X, Y, Z); |
41 |
} |
42 |
set |
43 |
{ |
44 |
X = value.X; |
45 |
Y = value.Y; |
46 |
Z = value.Z; |
47 |
} |
48 |
} |
49 |
|
50 |
public static Vector4 operator +(Vector4 v1, Vector4 v2) |
51 |
{ |
52 |
v1.X += v2.X; |
53 |
v1.Y += v2.Y; |
54 |
v1.Z += v2.Z; |
55 |
v1.W += v2.W; |
56 |
|
57 |
return v1; |
58 |
} |
59 |
|
60 |
public static Vector4 operator -(Vector4 v1, Vector4 v2) |
61 |
{ |
62 |
v1.X -= v2.X; |
63 |
v1.Y -= v2.Y; |
64 |
v1.Z -= v2.Z; |
65 |
v1.W -= v2.W; |
66 |
|
67 |
return v1; |
68 |
} |
69 |
|
70 |
public static Vector4 operator *(Vector4 v, float s) |
71 |
{ |
72 |
v.X *= s; |
73 |
v.Y *= s; |
74 |
v.Z *= s; |
75 |
v.W *= s; |
76 |
|
77 |
return v; |
78 |
} |
79 |
|
80 |
public static Vector4 operator *(float s, Vector4 v) => v * s; |
81 |
|
82 |
public static Vector4 operator /(Vector4 v, float s) => v * (1.0f / s); |
83 |
|
84 |
public static float Dot(Vector4 v1, Vector4 v2) => v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z + v1.W * v2.W; |
85 |
|
86 |
public static Vector4 Min(Vector4 v1, Vector4 v2) |
87 |
{ |
88 |
v1.X = (v1.X < v2.X) ? v1.X : v2.X; |
89 |
v1.Y = (v1.Y < v2.Y) ? v1.Y : v2.Y; |
90 |
v1.Z = (v1.Z < v2.Z) ? v1.Z : v2.Z; |
91 |
v1.W = (v1.W < v2.W) ? v1.W : v2.W; |
92 |
|
93 |
return v1; |
94 |
} |
95 |
|
96 |
public static Vector4 Max(Vector4 v1, Vector4 v2) |
97 |
{ |
98 |
v1.X = (v1.X > v2.X) ? v1.X : v2.X; |
99 |
v1.Y = (v1.Y > v2.Y) ? v1.Y : v2.Y; |
100 |
v1.Z = (v1.Z > v2.Z) ? v1.Z : v2.Z; |
101 |
v1.W = (v1.W > v2.W) ? v1.W : v2.W; |
102 |
|
103 |
return v1; |
104 |
} |
105 |
|
106 |
public static Vector4 Normalize(Vector4 v) => v * (1.0f / v.Length()); |
107 |
|
108 |
public float LengthSquared() => X * X + Y * Y + Z * Z + W * W; |
109 |
public float Length() => FMath.Sqrt(LengthSquared()); |
110 |
|
111 |
public static bool EqualsEps(Vector4 v1, Vector4 v2) |
112 |
{ |
113 |
Vector4 d = v2 - v1; |
114 |
|
115 |
float dx = Math.Abs(d.X); |
116 |
float dy = Math.Abs(d.Y); |
117 |
float dz = Math.Abs(d.Z); |
118 |
float dw = Math.Abs(d.W); |
119 |
|
120 |
return (dx < 0.0001f && dy < 0.0001f && dz < 0.0001f && dw < 0.0001f); |
121 |
} |
122 |
|
123 |
public static bool operator ==(Vector4 v1, Vector4 v2) => v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z && v1.W == v2.W; |
124 |
public static bool operator !=(Vector4 v1, Vector4 v2) => v1.X != v2.X || v1.Y != v2.Y || v1.Z != v2.Z || v1.W != v2.W; |
125 |
|
126 |
public bool Equals(Vector4 other) => X == other.X && Y == other.Y && Z == other.Z && W == other.W; |
127 |
public override bool Equals(object obj) => obj is Vector4 && Equals((Vector4)obj); |
128 |
public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); |
129 |
|
130 |
public override string ToString() => $"{{{X} {Y} {Z} {W}}}"; |
131 |
|
132 |
private static Vector4 zero = new Vector4(); |
133 |
private static Vector4 one = new Vector4(1.0f); |
134 |
private static Vector4 unitX = new Vector4(1.0f, 0.0f, 0.0f, 0.0f); |
135 |
private static Vector4 unitY = new Vector4(0.0f, 1.0f, 0.0f, 0.0f); |
136 |
private static Vector4 unitZ = new Vector4(0.0f, 0.0f, 1.0f, 0.0f); |
137 |
private static Vector4 unitW = new Vector4(0.0f, 0.0f, 0.0f, 1.0f); |
138 |
|
139 |
public static Vector4 Zero => zero; |
140 |
public static Vector4 One => one; |
141 |
public static Vector4 UnitX => unitX; |
142 |
public static Vector4 UnitY => unitY; |
143 |
public static Vector4 UnitZ => unitZ; |
144 |
public static Vector4 UnitW => unitW; |
145 |
} |
146 |
} |