Files
Project-M/Packages/com.rukhanka.animation/Rukhanka.Runtime/Common/Shaders/GPUStructures/BoneTransform.hlsl
T
2026-05-31 14:27:52 -07:00

120 lines
3.2 KiB
HLSL

#ifndef BONE_TRANFORM_HLSL_
#define BONE_TRANFORM_HLSL_
/////////////////////////////////////////////////////////////////////////////////
#include "Quaternion.hlsl"
/////////////////////////////////////////////////////////////////////////////////
struct BoneTransform
{
float3 pos;
Quaternion rot;
float3 scale;
static const uint size = (3 + 4 + 3) * 4;
/////////////////////////////////////////////////////////////////////////////////
static BoneTransform Identity()
{
BoneTransform rv;
rv.pos = 0;
rv.rot.value = float4(0, 0, 0, 1);
rv.scale = 1;
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
static BoneTransform Zero()
{
BoneTransform rv = (BoneTransform)0;
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
static BoneTransform FromMatrix(float3x4 m)
{
BoneTransform rv;
rv.rot = Quaternion::FromMatrix((float3x3)m);
rv.pos = m._m03_m13_m23;
float3 u = m._m00_m10_m20;
float3 v = m._m01_m11_m21;
float3 w = m._m02_m12_m22;
rv.scale = float3(length(u), length(v), length(w));
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
static BoneTransform Multiply(BoneTransform parent, BoneTransform child)
{
BoneTransform rv;
rv.pos = Quaternion::Rotate(parent.rot, child.pos * parent.scale) + parent.pos;
rv.rot = Quaternion::Multiply(parent.rot, child.rot);
rv.scale = parent.scale * child.scale;
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
static BoneTransform Scale(BoneTransform v, float3 scale)
{
v.pos *= scale.x;
v.rot.value *= scale.y;
v.scale *= scale.z;
return v;
}
/////////////////////////////////////////////////////////////////////////////////
float4x4 ToFloat4x4()
{
float3x3 rotMat = rot.ToRotationMatrix();
float4 c0 = float4(rotMat._11_21_31 * scale, pos.x);
float4 c1 = float4(rotMat._12_22_32 * scale, pos.y);
float4 c2 = float4(rotMat._13_23_33 * scale, pos.z);
float4 c3 = float4(0, 0, 0, 1);
float4x4 rv = float4x4(c0, c1, c2, c3);
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
static BoneTransform Inverse(BoneTransform v)
{
BoneTransform rv;
rv.rot = Quaternion::Inverse(v.rot);
rv.scale = rcp(v.scale);
rv.pos = Quaternion::Rotate(rv.rot, -v.pos * rv.scale);
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
static float3 TransformPoint(BoneTransform bt, float3 v)
{
float3 rv = Quaternion::Rotate(bt.rot, v * bt.scale) + bt.pos;
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
static float3 TransformDirection(BoneTransform bt, float3 v)
{
float3 rv = Quaternion::Rotate(bt.rot, v);
return rv;
}
};
/////////////////////////////////////////////////////////////////////////////////
#endif