Switch to non-branching approach for GetMajorAxes

This commit is contained in:
2026-03-28 21:27:46 +08:00
parent f620a650aa
commit 48a0e3facb
4 changed files with 62 additions and 58 deletions
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bb92af38d2a022242b4dddcb954f789e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+54
View File
@@ -0,0 +1,54 @@
#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;
}
@@ -1,58 +0,0 @@
#define EPSILON 0.0004f
/// Hidden
float CrossProduct(float2 A, float2 B)
{
return A.x * B.y - A.y * B.x;
}
/// Hidden
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);
if (xy_area > xz_area && xy_area > yz_area)
{
result[0].xyz = x_axes;
result[1].xyz = y_axes;
}
else if (xz_area > yz_area)
{
result[0].xyz = x_axes;
result[1].xyz = z_axes;
}
else
{
result[0].xyz = y_axes;
result[1].xyz = z_axes;
}
if (length(result[0].xyz) < 0.0004)
{
result[0].xyz = normalize(result[0].xyz) * EPSILON;
}
if (length(result[1].xyz) < 0.0004)
{
result[1].xyz = normalize(result[1].xyz) * EPSILON;
}
return result;
}