Math
Tide's math follows Unity.Mathematics, with Tide's naming: functions live on Math, in PascalCase. It's all deterministic: the same inputs give the same bits on every platform (see Determinism).
quaternion spin = quaternion.AxisAngle(float3(0, 1, 0), input.turn * time.dt);
trs.rotation = Math.Mul(trs.rotation, spin);
float3 forward = Math.Rotate(trs.rotation, float3(0, 0, 1));
trs.position += Math.Normalize(forward) * 5 * time.dt;
float2 flat = trs.position.xz;Types
| Type | What it is |
|---|---|
float2, float3, float4 |
Float vectors |
int2, int3, int4 |
Int vectors |
quaternion |
A rotation |
float2x2, float3x3, float4x4 |
Matrices, stored column by column |
They're lowercase built-in value types, like float. Angles are in radians: Math.Radians(degrees) and Math.Degrees(radians) convert.
Building values
- Vectors take any mix of scalars and vectors that adds up to their size,
float4(v.xy, 0, 1), or one scalar for every component,float3(1). float3(i)andint3(f)convert between int and float vectors, andint(x)andfloat(x)between scalars. Float to int truncates toward zero, saturates at the int range, and turns NaN into 0.- An int vector converts to a float vector of the same size by itself, like
inttofloat. quaternion(x, y, z, w),quaternion(float4)andquaternion(float3x3).- Matrices take one vector per column,
float3x3(c0, c1, c2), or all their numbers row by row: infloat2x2(1, 2, 3, 4),1, 2is the first row. Alsofloat3x3(quaternion), andfloat4x4(rotation, translation)from afloat3x3and afloat3.
Members
- Vectors have
x,y,zandw. - Swizzles read any combination:
v.xz,v.zyx,v.xxyy. They can be assigned too, as long as no component repeats:v.xz = float2(1, 2). - A
quaternion'svalueis afloat4, with (x, y, z) as the vector part. - A matrix's columns are
c0toc3.
Constants
Math.PI, Math.TAU, Math.E, quaternion.identity, float2x2.identity, float3x3.identity and float4x4.identity.
And these build values:
quaternion.AxisAngle(axis, angle)quaternion.Euler(radians): Z first, then X, then Y, Unity's default orderquaternion.LookRotation(forward, up)float4x4.TRS(translation, rotation, scale)float4x4.Translate(translation)
Operators
+ - * /work component by component on vectors, and%on int vectors. A scalar widens to the vector's size, and int to float, sov * 2 + 1works.- Matrices have
+and-with their own type, and*and/by a number. There's no*between matrices, or between a matrix and a vector: that'sMath.Mul. - Quaternions have no operators: combine rotations with
Math.Mul, and rotate vectors withMath.Rotate. - Comparisons and
==work on scalars only.
Functions
Component by component, on numbers and vectors:
Abs, Sign, Min, Max, Clamp (ints too), Floor, Ceil, Round (ties to even), Trunc, Frac, Sqrt, Rsqrt, Saturate, Radians, Degrees, Sin, Cos, Tan, Asin, Acos, Atan, Atan2, Exp, Exp2, Log, Log2, Log10, Pow, Step, Lerp, Unlerp, SmoothStep.
Vectors:
Dot, Cross, Length, LengthSq, Distance, DistanceSq, Normalize, NormalizeSafe (zero instead of NaN), Reflect, Csum, Cmin, Cmax.
Quaternions:
Mul (two rotations, or a rotation and a float3, which it rotates), Rotate, Inverse, Conjugate, Normalize, NormalizeSafe, Dot, Slerp, Nlerp, Forward, Up, Right, Angle.
Matrices:
Mul (two matrices, or a matrix and a vector of its size), Transpose, Inverse, Determinant, and for float4x4, Transform (a point) and Rotate (a direction).
Hashing:
Math.Hash(value) turns an int, int2, int3 or int4 into a random-looking int from 0 to 2147483647. The same value always gives the same number, on every machine. It keeps no state, so it works anywhere, parallel loops included:
// About one cell in four starts as sand, the same cells everywhere.
if (Math.Hash(int2(x, y)) % 4 == 0) field.cells[x, y] = Material.Sand;Put a seed in the value to get other numbers for the same cell: Math.Hash(int3(x, y, seed)). It's xxHash32, so every bit of the value changes every bit of the result.
Forgiving with bad values
Values can come from other players' input, so math avoids spreading NaN where it can:
Math.Clampalways returns a value in range: NaN gives the lower bound.Math.MinandMath.Maxwith one NaN argument return the other.Math.NormalizeSafegives zero for a zero vector, whereMath.Normalizewould give NaN.
Everywhere else, results match Unity.Mathematics. The transcendental functions (Sin, Exp, Pow and the others) are Tide's own, accurate to about 1 ulp, and give the same bits everywhere.