Swizzling is a GPU-supported operation that allows you to cheaply reorganize and repeat elements of a vector during an operation. Given its efficiency, it is very important to support swizzling in a language that targets GPUs. HLSL has special syntax where any scalar or vector can be swizzled; e.g., p.xyz takes a vector4 and returns its first 3 elements as a vector3, p.zyx reverses these elements, and p.xxy repeats the first element twice then pairs the result with the second element. Through C# extension methods, we can define some common swizzle combinations (e.g., xyz and zyx), but with repeated elements and considering vectors of size 4 (the max that is supported by GPUs), we’d have to define way too many extension methods to be complete. Rather, I’ve defined a few overloaded extensible extension methods where the swizzle indices are indicated as type parameters; e.g., considered swizzled quaternion transformation in C#:

Double3Bl m = -q.XYZ().Square; m = m.Sw<Y,X,X>() + m.Sw<Z,Z,Y>(); Double3Bl n = q.W * q.XYZ(); Double3Bl r = q.Sw<X,X,Y>() * q.Sw<Y,Z,Z>(); Double3Bl t = r.Sw<X,Z,Y>() - n.Sw<Z,X,Y>(); Double3Bl u = n.Sw<Y,Z,X>() + r.Sw<Y,X,Z>(); Double3Bl p = argB; Double3Bl v = m * p.XYZ() + t * p.YZX() + u * p.ZXY(); return 2d * v + p.XYZ();

Sometimes we use extension methods (e.g., XYZ()), and sometimes we use the Sw method, which is slightly more verbose but still reasonably concise. For type safety, we define the X, Y, Z, and W classes so that X <: Y <: Z <: W, then if the target is a 4 vector, the type parameter bounds for all the swizzle parameters is W , while if it’s a 2 vector, the type parameter bounds for all the swizzle parameters is Y, disallowing Z and W. The X, Y, Z, and W classes can then be instantiated as type parameters to determine the index they represent.