Files
UnrealEngine/Engine/Shaders/Private/BoneTransform.ush
2025-05-18 13:04:45 +08:00

129 lines
3.7 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Common.ush"
#include "Quaternion.ush"
struct FBoneTransform
{
FQuat Rotation;
float3 Location;
};
struct FBoneTransformWithScale
{
FQuat Rotation;
float3 Location;
float3 Scale;
};
////
FBoneTransform MakeBoneTransform(FQuat Rotation, float3 Location)
{
FBoneTransform Transform;
Transform.Rotation = Rotation;
Transform.Location = Location;
return Transform;
}
FBoneTransform MakeBoneTransformIdentity()
{
return MakeBoneTransform(
QuatIdentity(),
float3(0.0f, 0.0f, 0.0f)
);
}
FBoneTransform MultiplyBoneTransform(FBoneTransform Atom1, FBoneTransform Atom2)
{
FQuat Rotation = QuatMultiply(Atom2.Rotation, Atom1.Rotation);
float3 Location = QuatRotateVector(Atom2.Rotation, Atom1.Location) + Atom2.Location;
return MakeBoneTransform(Rotation, Location);
}
FBoneTransform InvertBoneTransform(FBoneTransform Transform)
{
FQuat Rotation = QuatConjugate(Transform.Rotation);
float3 Location = -QuatRotateVector(Rotation, Transform.Location);
return MakeBoneTransform(Rotation, Location);
}
FBoneTransform RemoveBoneTransformScale(FBoneTransformWithScale Transform)
{
FBoneTransform Result;
Result.Location = Transform.Location;
Result.Rotation = QuatNormalize(Transform.Rotation);
return Result;
}
float4x4 MatrixFromBoneTransform(FBoneTransform Transform)
{
float3x3 RotationMatrix = QuatToMatrix(Transform.Rotation);
float4x4 OutMatrix;
OutMatrix[0] = float4(RotationMatrix[0], 0.0);
OutMatrix[1] = float4(RotationMatrix[1], 0.0);
OutMatrix[2] = float4(RotationMatrix[2], 0.0);
OutMatrix[3] = float4(Transform.Location, 1.0);
return OutMatrix;
}
FBoneTransform BlendBoneTransforms(FBoneTransform Atom1, FBoneTransform Atom2, float Alpha)
{
FBoneTransform Blended;
Blended.Location = lerp(Atom1.Location, Atom2.Location, Alpha);
Blended.Rotation = QuatSlerpApproximate(Atom1.Rotation, Atom2.Rotation, Alpha);
return Blended;
}
////
FBoneTransformWithScale MakeBoneTransformWithScale(FQuat Rotation, float3 Location, float3 Scale)
{
FBoneTransformWithScale Transform;
Transform.Rotation = Rotation;
Transform.Location = Location;
Transform.Scale = Scale;
return Transform;
}
FBoneTransformWithScale MakeBoneTransformWithScaleIdentity()
{
return MakeBoneTransformWithScale(QuatIdentity(), float3(0.0f, 0.0f, 0.0f), float3(1.0f, 1.0f, 1.0f));
}
FBoneTransformWithScale MultiplyBoneTransformWithScale(FBoneTransformWithScale Atom1, FBoneTransformWithScale Atom2)
{
// NOTE: Assumes no negative scale! Otherwise should multiply using matrices
FQuat Rotation = QuatMultiply(Atom2.Rotation, Atom1.Rotation);
float3 Location = QuatRotateVector(Atom2.Rotation, Atom2.Scale * Atom1.Location) + Atom2.Location;
float3 Scale = Atom1.Scale * Atom2.Scale;
return MakeBoneTransformWithScale(Rotation, Location, Scale);
}
float4x4 MatrixFromBoneTransformWithScale(FBoneTransformWithScale Transform)
{
float3x3 RotationMatrix = QuatToMatrix(Transform.Rotation);
RotationMatrix[0] *= Transform.Scale.xxx;
RotationMatrix[1] *= Transform.Scale.yyy;
RotationMatrix[2] *= Transform.Scale.zzz;
float4x4 OutMatrix;
OutMatrix[0] = float4(RotationMatrix[0], 0.0);
OutMatrix[1] = float4(RotationMatrix[1], 0.0);
OutMatrix[2] = float4(RotationMatrix[2], 0.0);
OutMatrix[3] = float4(Transform.Location, 1.0);
return OutMatrix;
}
FBoneTransformWithScale BlendBoneTransformsWithScale(FBoneTransformWithScale Atom1, FBoneTransformWithScale Atom2, float Alpha)
{
FBoneTransformWithScale Blended;
Blended.Location = lerp(Atom1.Location, Atom2.Location, Alpha);
Blended.Rotation = QuatSlerpApproximate(Atom1.Rotation, Atom2.Rotation, Alpha);
Blended.Scale = lerp(Atom1.Scale, Atom2.Scale, Alpha);
return Blended;
}