120 lines
3.2 KiB
HLSL
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
|
|
|
|
|