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

54 lines
1.8 KiB
HLSL

#ifndef AVATAR_MASK_HLSL_
#define AVATAR_MASK_HLSL_
/////////////////////////////////////////////////////////////////////////////////
// uint
ByteAddressBuffer avatarMasksBuffer;
/////////////////////////////////////////////////////////////////////////////////
bool IsBoneInGenericAvatarMask(int avatarMaskDataOffset, int boneIndex)
{
int uintIndex = boneIndex >> 5; // boneIndex / 32
int byteOffsetInUint = boneIndex & 0x1f; // boneIndex % 32
uint boneMask = 1u << byteOffsetInUint;
// First uint in mask is human body parts mask, skip it
uint absMaskDataIndex = avatarMaskDataOffset + 1 + uintIndex;
uint avatarMask = avatarMasksBuffer.Load(absMaskDataIndex * 4);
CHECK_RAW_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_GPUANIMATOR_GENERIC_AVATAR_AVATAR_MASK_BUFFER_READ, absMaskDataIndex * 4, 4, avatarMasksBuffer);
return (avatarMask & boneMask) != 0;
}
/////////////////////////////////////////////////////////////////////////////////
bool IsBoneInHumanAvatarMask(int avatarMaskDataOffset, int humanAvatarMaskBodyPart)
{
uint absMaskDataIndex = avatarMaskDataOffset;
uint humanAvatarMask = avatarMasksBuffer.Load(absMaskDataIndex * 4);
CHECK_RAW_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_GPUANIMATOR_HUMANOID_AVATAR_AVATAR_MASK_BUFFER_READ, absMaskDataIndex * 4, 4, avatarMasksBuffer);
return (humanAvatarMask & 1 << humanAvatarMaskBodyPart) != 0;
}
/////////////////////////////////////////////////////////////////////////////////
bool IsBoneInAvatarMask(int avatarMaskDataOffset, int humanAvatarMaskBodyPart, int boneIndex)
{
if (avatarMaskDataOffset < 0)
return true;
bool rv = humanAvatarMaskBodyPart < 0 ?
IsBoneInGenericAvatarMask(avatarMaskDataOffset, boneIndex) :
IsBoneInHumanAvatarMask(avatarMaskDataOffset, humanAvatarMaskBodyPart);
return rv;
}
#endif