// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "/Engine/Private/GpuSkinCommon.ush" uint ReadNumBones( Buffer InputWeightLookupStream, uint NumBoneInfluences, uint VertexIndex ) { #if !ENABLE_DEFORMER_BONES return 1; #elif GPUSKIN_UNLIMITED_BONE_INFLUENCE const uint BufferIndex = VertexIndex; uint BlendOffsetCount = InputWeightLookupStream[BufferIndex]; return BlendOffsetCount & 0xff; #else // !GPUSKIN_UNLIMITED_BONE_INFLUENCE return NumBoneInfluences; #endif } float ReadBoneWeight( Buffer InputWeightLookupStream, uint InputWeightIndexSize, Buffer InputWeightStream, uint InputWeightStride, uint NumBoneInfluences, uint VertexIndex, uint BoneIndex ) { #if !ENABLE_DEFORMER_BONES return 1; #elif GPUSKIN_UNLIMITED_BONE_INFLUENCE const uint BufferIndex = VertexIndex; uint BlendOffsetCount = InputWeightLookupStream[BufferIndex]; int NumBoneInfluencesLocal = BlendOffsetCount & 0xff; int StreamOffset = BlendOffsetCount >> 8; int BoneIndexSize = InputWeightIndexSize & 0xff; int BoneWeightSize = InputWeightIndexSize >> 8; int WeightsOffset = StreamOffset + (BoneIndexSize * NumBoneInfluencesLocal); int BoneWeightOffset = WeightsOffset + BoneIndex * BoneWeightSize; if (BoneWeightSize > 1) { return float(InputWeightStream[BoneWeightOffset + 1] << 8 | InputWeightStream[BoneWeightOffset]) / 65535.0; } else { return float(InputWeightStream[BoneWeightOffset]) / 255.0f; } #else // !GPUSKIN_UNLIMITED_BONE_INFLUENCE uint StreamOffset = (VertexIndex * (InputWeightStride / 4)); float BlendWeight = GetBlendWeights(InputWeightStream, StreamOffset, BoneIndex / 4, NumBoneInfluences)[BoneIndex & 0x3]; return BlendWeight; #endif } float3x4 GetBoneMatrix(Buffer BoneMatrices, uint BoneIndex) { uint BufferIndex = BoneIndex * 3; return float3x4(BoneMatrices[BufferIndex], BoneMatrices[BufferIndex + 1], BoneMatrices[BufferIndex + 2]); } float3x4 ReadBoneMatrix( Buffer InputWeightLookupStream, uint InputWeightIndexSize, Buffer InputWeightStream, uint InputWeightStride, Buffer BoneMatrices, uint VertexIndex, uint BoneIndex ) { #if !ENABLE_DEFORMER_BONES return float3x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0); #elif GPUSKIN_UNLIMITED_BONE_INFLUENCE const uint BufferIndex = VertexIndex; uint BlendOffsetCount = InputWeightLookupStream[BufferIndex]; int StreamOffset = BlendOffsetCount >> 8; int BoneIndexSize = InputWeightIndexSize & 0xff; int BoneIndexOffset = StreamOffset + (BoneIndexSize * BoneIndex); int BoneGlobalIndex = InputWeightStream[BoneIndexOffset]; if (BoneIndexSize > 1) { BoneGlobalIndex = InputWeightStream[BoneIndexOffset + 1] << 8 | BoneGlobalIndex; } return GetBoneMatrix(BoneMatrices, BoneGlobalIndex); #else // !GPUSKIN_UNLIMITED_BONE_INFLUENCE uint StreamOffset = (VertexIndex * (InputWeightStride / 4)); int BlendIndex = GetBlendIndices(InputWeightStream ,StreamOffset, BoneIndex / 4)[BoneIndex & 0x3]; return GetBoneMatrix(BoneMatrices,BlendIndex); #endif } float3x4 ReadWeightedBoneMatrix( Buffer InputWeightLookupStream, uint InputWeightIndexSize, Buffer InputWeightStream, uint InputWeightStride, uint NumBoneInfluences, Buffer BoneMatrices, uint VertexIndex ) { #if !ENABLE_DEFORMER_BONES return float3x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0); #elif GPUSKIN_UNLIMITED_BONE_INFLUENCE const uint BufferIndex = VertexIndex; const uint BlendOffsetCount = InputWeightLookupStream[BufferIndex]; return ComputeBoneMatrixWithUnlimitedInfluences(BoneMatrices, InputWeightStream, InputWeightIndexSize, BlendOffsetCount); #else const uint StreamOffset = (VertexIndex * (InputWeightStride / 4)); const uint NumInfluences = NumBoneInfluences; FGPUSkinIndexAndWeight IndicesAndWeights = (FGPUSkinIndexAndWeight)0; if (NumInfluences > 0) { IndicesAndWeights.BlendIndices = GetBlendIndices(InputWeightStream, StreamOffset, 0); IndicesAndWeights.BlendWeights = GetBlendWeights(InputWeightStream, StreamOffset, 0, NumInfluences); } if (NumInfluences > 4) { IndicesAndWeights.BlendIndices2 = GetBlendIndices(InputWeightStream, StreamOffset, 1); IndicesAndWeights.BlendWeights2 = GetBlendWeights(InputWeightStream, StreamOffset, 1, NumInfluences); } return ComputeBoneMatrixWithLimitedInfluences(BoneMatrices, IndicesAndWeights, NumInfluences > 4); #endif }