| 1 | using System; | 
 
 
 
 
 | 2 |  | 
 
 
 
 
 | 3 | namespace 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 | } |