mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
105 lines
2.3 KiB
Beef
105 lines
2.3 KiB
Beef
using System;
|
|
|
|
namespace GlitchyEngine.Math
|
|
{
|
|
/**
|
|
* Generates component swizzle operators for a vector.
|
|
*/
|
|
[AttributeUsage(.Struct | .Class)]
|
|
struct SwizzleVectorAttribute : Attribute, IComptimeTypeApply
|
|
{
|
|
private int _vectorSize;
|
|
|
|
public int VectorSize => _vectorSize;
|
|
|
|
private String _vectorTypeName;
|
|
|
|
this(int vectorSize, String vectorTypeName)
|
|
{
|
|
_vectorSize = vectorSize;
|
|
_vectorTypeName = vectorTypeName;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the swizzle operator is invalid (same component assigned twice).
|
|
*/
|
|
static bool IsSetterValid(int[4] cmp, int vecSize)
|
|
{
|
|
return cmp[0] == cmp[1] || (vecSize >= 3 && cmp[0] == cmp[2]) || (vecSize == 4 && cmp[0] == cmp[3]) ||
|
|
(vecSize >= 3 && cmp[1] == cmp[2]) || (vecSize == 4 && cmp[1] == cmp[3]) ||
|
|
(vecSize == 4 && cmp[2] == cmp[3]);
|
|
}
|
|
|
|
[Comptime]
|
|
public void ApplyToType(Type type)
|
|
{
|
|
String[4] componentNames = .("X", "Y", "Z", "W");
|
|
|
|
for(int swizzleCount = 2; swizzleCount <= 4; swizzleCount++)
|
|
{
|
|
int[4] cmp = .();
|
|
|
|
int cmp2max = swizzleCount > 2 ? _vectorSize : 1;
|
|
int cmp3max = swizzleCount > 3 ? _vectorSize : 1;
|
|
|
|
for(cmp[0] = 0; cmp[0] < _vectorSize; cmp[0]++)
|
|
for(cmp[1] = 0; cmp[1] < _vectorSize; cmp[1]++)
|
|
for(cmp[2] = 0; cmp[2] < cmp2max; cmp[2]++)
|
|
for(cmp[3] = 0; cmp[3] < cmp3max; cmp[3]++)
|
|
{
|
|
String swizzleName = scope String(swizzleCount);
|
|
String swizzleConstructor = scope String(swizzleCount * 3);
|
|
String setter = scope String(128);
|
|
|
|
bool setterInvalid = IsSetterValid(cmp, swizzleCount);
|
|
|
|
if (!setterInvalid)
|
|
{
|
|
setter.Append(
|
|
"""
|
|
set mut
|
|
{
|
|
""");
|
|
}
|
|
|
|
for(int c = 0; c < swizzleCount; c++)
|
|
{
|
|
swizzleName.Append(componentNames[cmp[c]]);
|
|
|
|
if(c != 0)
|
|
{
|
|
swizzleConstructor.Append(", ");
|
|
}
|
|
swizzleConstructor.Append(componentNames[cmp[c]]);
|
|
|
|
if(!setterInvalid && c < _vectorSize)
|
|
{
|
|
setter.AppendF($"\n\t\t{componentNames[cmp[c]]} = value.{componentNames[c]};");
|
|
}
|
|
}
|
|
|
|
if (!setterInvalid)
|
|
{
|
|
setter.Append(
|
|
"""
|
|
|
|
}
|
|
""");
|
|
}
|
|
|
|
String swizzleString = scope $"""
|
|
public {_vectorTypeName}{swizzleCount} {swizzleName}
|
|
{{
|
|
get => .({swizzleConstructor});
|
|
{setter}
|
|
}}
|
|
|
|
""";
|
|
|
|
Compiler.EmitTypeBody(type, swizzleString);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|