54 lines
1.4 KiB
HLSL
54 lines
1.4 KiB
HLSL
#define EPSILON 0.0004f
|
|
|
|
float CrossProduct(float2 A, float2 B)
|
|
{
|
|
return A.x * B.y - A.y * B.x;
|
|
}
|
|
|
|
float SweepArea(float2 A, float2 B)
|
|
{
|
|
return abs(CrossProduct(A, B));
|
|
}
|
|
|
|
float4x4 GetMajorAxes(float4x4 Axes, float4x4 AxesProjections)
|
|
{
|
|
float4x4 result = (float4x4)0;
|
|
|
|
float2 x_proj = AxesProjections[0].xy;
|
|
float2 y_proj = AxesProjections[1].xy;
|
|
float2 z_proj = AxesProjections[2].xy;
|
|
|
|
float3 x_axes = Axes[0].xyz;
|
|
float3 y_axes = Axes[1].xyz;
|
|
float3 z_axes = Axes[2].xyz;
|
|
|
|
float xy_area = SweepArea(x_proj, y_proj);
|
|
float xz_area = SweepArea(x_proj, z_proj);
|
|
float yz_area = SweepArea(y_proj, z_proj);
|
|
|
|
// Compute selection weights using step
|
|
float xy_is_max = step(xz_area, xy_area) * step(yz_area, xy_area);
|
|
float xz_is_max = step(yz_area, xz_area) * (1.0 - xy_is_max);
|
|
float yz_is_max = 1.0 - xy_is_max - xz_is_max;
|
|
|
|
// Select axis0
|
|
float3 axis0 =
|
|
xy_is_max * x_axes +
|
|
xz_is_max * x_axes +
|
|
yz_is_max * y_axes;
|
|
|
|
// Select axis1
|
|
float3 axis1 =
|
|
xy_is_max * y_axes +
|
|
xz_is_max * z_axes +
|
|
yz_is_max * z_axes;
|
|
|
|
// Normalize and scale if length is below threshold
|
|
float len0 = length(axis0);
|
|
float len1 = length(axis1);
|
|
|
|
result[0].xyz = normalize(axis0) * max(len0, EPSILON);
|
|
result[1].xyz = normalize(axis1) * max(len1, EPSILON);
|
|
|
|
return result;
|
|
} |