C# Math
Math API has some structs and functions that might help you with the development.
Note
It’s not complete at all and misses a bunch of functionality, but anyways it’s here :)
Vector2 & UVector2
It is a utility struct representing 2D vector.
UVector2D has the same functionality as Vector2D.
[StructLayout(LayoutKind.Sequential)]
public struct Vector2 : IEquatable<Vector2>
{
public float X;
public float Y;
public Vector2(Vector2 v);
public Vector2(float scalar);
public Vector2(float x, float y);
public static Vector2 operator+ (Vector2 left, Vector2 right);
public static Vector2 operator+ (Vector2 left, float scalar);
public static Vector2 operator+ (float scalar, Vector2 right);
public static Vector2 operator- (Vector2 left, Vector2 right);
public static Vector2 operator- (Vector2 left, float scalar);
public static Vector2 operator- (float scalar, Vector2 right);
public static Vector2 operator- (Vector2 vector);
public static Vector2 operator* (Vector2 left, Vector2 right);
public static Vector2 operator* (Vector2 left, float scalar);
public static Vector2 operator* (float scalar, Vector2 right);
public static Vector2 operator/ (Vector2 left, Vector2 right);
public static Vector2 operator/ (Vector2 left, float scalar);
public static Vector2 operator/ (float scalar, Vector2 right);
public override bool Equals(object obj);
public bool Equals(Vector2 right);
public static bool operator== (Vector2 left, Vector2 right);
public static bool operator!= (Vector2 left, Vector2 right);
public override string ToString();
}
Vector3
It is a utility struct representing 3D vector. It has the same functionality as Vector2D but additionally, it has a construct that takes Color3 vector and an implicit cast operator.
Vector3 and Color3 structs are identical. They can be used in your scripts so that the editor can distinguish them and display an appropriate way of editing it. For example, for a Color3 value, there will be a color picker.
[StructLayout(LayoutKind.Sequential)]
public struct Vector3 : IEquatable<Vector3>
{
public float X;
public float Y;
public float Z;
public Vector3 (Color3 value)
{
X = value.R;
Y = value.G;
Z = value.B;
}
public static implicit operator Vector3(Color3 value);
...
}
Vector4
It is a utility struct representing 4D vector. It has the same functionality as Vector3D but instead of Color3, it works with Color4.
Vector4 and Color4 structs are identical. They can be used so that the editor can distinguish them and display an appropriate way of editing it. For example, for a Color4 value, there will be a color-alpha picker.
Quat
It represents a quaternion that can be used for rotations.
[StructLayout(LayoutKind.Sequential)]
public struct Quat : IEquatable<Quat>
{
public float X;
public float Y;
public float Z;
public float W;
public Quat(float w, float x, float y, float z);
public Quat(float w, Vector3 v);
public static Quat Conjugate(Quat val);
public static float Dot(Quat left, Quat right);
public Quat Inverse();
public float Lenght();
// Turns it into a unit length quat
public void Normalize();
// Returns in radians. X - pitch, Y - yaw, Z - roll
public Vector3 EulerAngles();
public static Quat FromEulerAngles(Vector3 radians);
public static Quat Unit()
{
return new Quat(1f, 0f, 0f, 0f);
}
public static Quat operator* (Quat left, Quat right);
public static Quat operator/ (Quat left, float scalar);
public override bool Equals(object obj);
public bool Equals(Quat right);
public static bool operator== (Quat left, Quat right);
public static bool operator!= (Quat left, Quat right);
public override string ToString();
public override int GetHashCode();
}
Rotator
Currently, it just contains a Quat member
[StructLayout(LayoutKind.Sequential)]
public struct Rotator
{
public Quat Rotation;
public static implicit operator Rotator(Quat value);
}
Transform
It is used to represent an objects transformation
[StructLayout(LayoutKind.Sequential)]
public struct Transform
{
public Vector3 Location;
public Rotator Rotation;
public Vector3 Scale;
}
AABB
It is used to represent an objects extents
[StructLayout(LayoutKind.Sequential)]
public struct AABB
{
public Vector3 Min;
public Vector3 Max;
public AABB(Vector3 min, Vector3 max);
public static AABB Default()
{
AABB result = new AABB();
result.Min = new Vector3(float.MinValue);
result.Max = new Vector3(float.MaxValue);
return result;
}
public Vector3 Center() { return (Min + Max) * 0.5f; }
public Vector3 Extents() { return Max - Min; }
public float Length() { return Mathf.Length(Extents()); }
public void Grow(AABB other);
public void Grow(Vector3 p);
public bool Contains(Vector3 p);
// Return min/max extents value
public float MinSide();
public float MaxSide();
public static bool Overlap(AABB a, AABB b);
public override bool Equals(object obj);
public bool Equals(AABB right);
public static bool operator ==(AABB left, AABB right);
public static bool operator !=(AABB left, AABB right);
public override string ToString();
public override int GetHashCode();
}
Math
It is a static class that contains utility functions.
public static class Mathf
{
public static float Clamp(float value, float min, float max);
public static Vector2 Clamp(in Vector2 value, float min, float max);
public static Vector2 Clamp(in Vector2 value, in Vector2 min, in Vector2 max);
public static Vector3 Clamp(in Vector3 value, float min, float max);
public static Vector3 Clamp(in Vector3 value, in Vector3 min, in Vector3 max);
public static Vector4 Clamp(in Vector4 value, float min, float max);
public static Vector4 Clamp(in Vector4 value, in Vector4 min, in Vector4 max);
// Converts angles to radians
public static float Radians(float angle);
// Converts radians to angles
public static float Degrees(float radians);
// Projects vector `v` on a plane with normal `n`
public static Vector3 Project(Vector3 v, Vector3 n);
// It can be used to get a quaternion that represent a rotation around an axis
public static Quat AngleAxis(float angle, Vector3 v);
public static Vector3 Reflect(Vector3 v, Vector3 normal);
public static float Length(Vector2 v);
public static float Length(Vector3 v);
public static float Length(Vector4 v);
public static Vector2 Normalize(Vector2 v);
public static Vector3 Normalize(Vector3 v);
public static Vector4 Normalize(Vector4 v);
public static float Dot(Vector2 lhs, Vector2 rhs) => (lhs.X * rhs.X + lhs.Y * rhs.Y);
public static float Dot(Vector3 lhs, Vector3 rhs) => (lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z);
public static float Dot(Vector4 lhs, Vector4 rhs) => (lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z + lhs.W * rhs.W);
public static float Lerp(float x, float y, float alpha);
public static Vector2 Lerp(Vector2 x, Vector2 y, float alpha);
public static Vector3 Lerp(Vector3 x, Vector3 y, float alpha);
public static Vector4 Lerp(Vector4 x, Vector4 y, float alpha);
public static float Step(float edge, float x) => x < edge ? 0.0f : 1.0f;
public static Vector2 Step(Vector2 edge, Vector2 x) => new Vector2(Step(edge.X, x.X), Step(edge.Y, x.Y));
public static Vector3 Step(Vector3 edge, Vector3 x) => new Vector3(Step(edge.X, x.X), Step(edge.Y, x.Y), Step(edge.Z, x.Z));
public static Vector4 Step(Vector4 edge, Vector4 x) => new Vector4(Step(edge.X, x.X), Step(edge.Y, x.Y), Step(edge.Z, x.Z), Step(edge.W, x.W));
public static float Floor(float x) => (float)Math.Floor(x);
public static Vector2 Floor(Vector2 x) => new Vector2((float)Math.Floor(x.X), (float)Math.Floor(x.Y));
public static Vector3 Floor(Vector3 x) => new Vector3((float)Math.Floor(x.X), (float)Math.Floor(x.Y), (float)Math.Floor(x.Z));
public static Vector4 Floor(Vector4 x) => new Vector4((float)Math.Floor(x.X), (float)Math.Floor(x.Y), (float)Math.Floor(x.Z), (float)Math.Floor(x.W));
public static float Abs(float x) => (float)Math.Abs(x);
public static Vector2 Abs(Vector2 x) => new Vector2((float)Math.Abs(x.X), (float)Math.Abs(x.Y));
public static Vector3 Abs(Vector3 x) => new Vector3((float)Math.Abs(x.X), (float)Math.Abs(x.Y), (float)Math.Abs(x.Z));
public static Vector4 Abs(Vector4 x) => new Vector4((float)Math.Abs(x.X), (float)Math.Abs(x.Y), (float)Math.Abs(x.Z), (float)Math.Abs(x.W));
public static float Fract(float x) => x - Floor(x);
public static Vector2 Fract(Vector2 x) => x - Floor(x);
public static Vector3 Fract(Vector3 x) => x - Floor(x);
public static Vector4 Fract(Vector4 x) => x - Floor(x);
public static float Min(float a, float b) => Math.Min(a, b);
public static Vector2 Min(Vector2 a, Vector2 b) => new Vector2(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y));
public static Vector3 Min(Vector3 a, Vector3 b) => new Vector3(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Min(a.Z, b.Z));
public static Vector4 Min(Vector4 a, Vector4 b) => new Vector4(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Min(a.Z, b.Z), Math.Min(a.W, b.W));
public static float Max(float a, float b) => Math.Max(a, b);
public static Vector2 Max(Vector2 a, Vector2 b) => new Vector2(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y));
public static Vector3 Max(Vector3 a, Vector3 b) => new Vector3(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y), Math.Max(a.Z, b.Z));
public static Vector4 Max(Vector4 a, Vector4 b) => new Vector4(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y), Math.Max(a.Z, b.Z), Math.Max(a.W, b.W));
// All components are in the range [0; 1], including hue.
public static Color3 RGB2HSV(Color3 c);
// All components are in the range [0; 1], including hue.
public static Color3 HSV2RGB(Color3 c);
// Input values are RGB colors. They're converted into HSV, lerped, and converted back to RGB
public static Color3 ColorLerp(Color3 x, Color3 y, float alpha);
// Maps `value` from range [minA; maxA] to range [minB; maxB]
public static float MapRange(float value, float minA, float maxA, float minB, float maxB);
public static float Sign(float v) => Math.Sign(v);
public static Vector2 Sign(Vector2 v) => new Vector2(Math.Sign(v.X), Math.Sign(v.Y));
public static Vector3 Sign(Vector3 v) => new Vector3(Math.Sign(v.X), Math.Sign(v.Y), Math.Sign(v.Z));
public static Vector4 Sign(Vector4 v) => new Vector4(Math.Sign(v.X), Math.Sign(v.Y), Math.Sign(v.Z), Math.Sign(v.W));
}