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
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
|