You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
2.9 KiB
HLSL

/******************************************************************************/
/*
Project - MudBun
Publisher - Long Bunny Labs
http://LongBunnyLabs.com
Author - Ming-Lun "Allen" Chou
http://AllenChou.net
*/
/******************************************************************************/
#ifndef MUDBUN_VECTOR
#define MUDBUN_VECTOR
#include "MathConst.cginc"
#define kUnitX (float3(1.0f, 0.0f, 0.0f))
#define kUnitY (float3(0.0f, 1.0f, 0.0f))
#define kUnitZ (float3(0.0f, 0.0f, 1.0f))
#define kOrigin (float3(0.0f, 0.0f, 0.0f))
float3 normalize_safe(float3 v, float3 fallback, float epsilon)
{
float vv = dot(v, v);
return vv > epsilon ? v / sqrt(vv) : fallback;
}
float3 normalize_safe(float3 v, float3 fallback)
{
return normalize_safe(v, fallback, kEpsilon);
}
float3 normalize_safe(float3 v)
{
return normalize_safe(v, kUnitZ);
}
float3 project_vec(float3 v, float3 onto)
{
onto = normalize(onto);
return dot(v, onto) * onto;
}
float3 project_plane(float3 v, float3 n)
{
return v - project_vec(v, n);
}
float3 limit_length(float3 v, float maxLen)
{
return min(maxLen, length(v)) * normalize_safe(v, 0.0f);
}
float3 find_ortho(float3 v)
{
if (v.x >= kSqrt3Inv)
return float3(v.y, -v.x, 0.0);
else
return float3(0.0, v.z, -v.y);
}
float3 find_ortho_consistent(float3 v)
{
return normalize_safe(cross(v, kUnitY), kUnitX);
}
void form_orthonormal_basis(float3 v, out float3 a, out float3 b)
{
a = normalize(find_ortho(v));
b = cross(v, a);
}
// a and b must be normalized
float angle_between(float3 a, float3 b)
{
return acos(clamp(dot(a, b), -1.0f, 1.0f));
}
float3 slerp(float3 a, float3 b, float t)
{
float d = dot(normalize(a), normalize(b));
if (d > kEpsilonComp)
{
return lerp(a, b, t);
}
float r = acos(clamp(d, -1.0f, 1.0f));
return (sin((1.0 - t) * r) * a + sin(t * r) * b) / sin(r);
}
float3 nlerp(float3 a, float b, float t)
{
return normalize(lerp(a, b, t));
}
float3x3 mat_basis(float3 xAxis, float3 yAxis, float3 zAxis)
{
return transpose(float3x3(xAxis, yAxis, zAxis));
}
float3x3 mat_look_at(float3 dir, float3 up)
{
float3 zAxis = normalize_safe(dir, kUnitZ);
float3 xAxis = normalize_safe(cross(up, zAxis), kUnitX);
float3 yAxis = cross(zAxis, xAxis);
return mat_basis(xAxis, yAxis, zAxis);
}
float3 cartesian_to_spherical(float3 p)
{
float r = length(p);
return float3(r, atan2(p.z, p.x), acos(p.y / r));
}
float3 spherical_to_cartesian(float3 p)
{
float s = sin(p.z);
return p.x * float3(cos(p.y) * s, cos(p.z), sin(p.y) * s);
}
float comp_sum(float2 v)
{
return dot(v, float2(1.0f, 1.0f));
}
float comp_sum(float3 v)
{
return dot(v, float3(1.0f, 1.0f, 1.0f));
}
float comp_sum(float4 v)
{
return dot(v, float4(1.0f, 1.0f, 1.0f, 1.0f));
}
float min_comp(float3 v)
{
return min(v.x, min(v.y, v.z));
}
float max_comp(float3 v)
{
return max(v.x, max(v.y, v.z));
}
float3 quantize(float3 v, float step)
{
return round(v / step) * step;
}
#endif