bool UBlendSpaceBase::GetSamplesFromBlendInput(const FVector &BlendInput, TArray<FBlendSampleData> & OutSampleDataList) const { static TArray<FGridBlendSample, TInlineAllocator<4> > RawGridSamples; check(IsInGameThread() && !RawGridSamples.Num()); // this must be called non-recursively from the gamethread GetRawSamplesFromBlendInput(BlendInput, RawGridSamples); OutSampleDataList.Reset(); OutSampleDataList.Reserve(RawGridSamples.Num() * FEditorElement::MAX_VERTICES); // consolidate all samples for (int32 SampleNum=0; SampleNum<RawGridSamples.Num(); ++SampleNum) { FGridBlendSample& GridSample = RawGridSamples[SampleNum]; float GridWeight = GridSample.BlendWeight; FEditorElement& GridElement = GridSample.GridElement; for(int Ind = 0; Ind < GridElement.MAX_VERTICES; ++Ind) { if(GridElement.Indices[Ind] != INDEX_NONE) { int32 Index = OutSampleDataList.AddUnique(GridElement.Indices[Ind]); OutSampleDataList[Index].AddWeight(GridElement.Weights[Ind]*GridWeight); } } } /** Used to sort by Weight. */ struct FCompareFBlendSampleData { FORCEINLINE bool operator()( const FBlendSampleData& A, const FBlendSampleData& B ) const { return B.TotalWeight < A.TotalWeight; } }; OutSampleDataList.Sort( FCompareFBlendSampleData() ); // remove noisy ones int32 TotalSample = OutSampleDataList.Num(); float TotalWeight = 0.f; for (int32 I=0; I<TotalSample; ++I) { if (OutSampleDataList[I].TotalWeight < ZERO_ANIMWEIGHT_THRESH) { // cut anything in front of this OutSampleDataList.RemoveAt(I, TotalSample-I, false); // we won't shrink here, that might screw up alloc optimization at a higher level, if not this is temp anyway break; } TotalWeight += OutSampleDataList[I].TotalWeight; } for (int32 I=0; I<OutSampleDataList.Num(); ++I) { // normalize to all weights OutSampleDataList[I].TotalWeight /= TotalWeight; } RawGridSamples.Reset(); return (OutSampleDataList.Num()!=0); }
bool UBlendSpaceBase::GetSamplesFromBlendInput(const FVector &BlendInput, TArray<FBlendSampleData> & OutSampleDataList) const { TArray<FGridBlendSample> RawGridSamples; GetRawSamplesFromBlendInput(BlendInput, RawGridSamples); OutSampleDataList.Empty(); // consolidate all samples for (int32 SampleNum=0; SampleNum<RawGridSamples.Num(); ++SampleNum) { FGridBlendSample& GridSample = RawGridSamples[SampleNum]; float GridWeight = GridSample.BlendWeight; FEditorElement& GridElement = GridSample.GridElement; for(int Ind = 0; Ind < GridElement.MAX_VERTICES; ++Ind) { if(GridElement.Indices[Ind] != INDEX_NONE) { int32 Index = OutSampleDataList.AddUnique(GridElement.Indices[Ind]); OutSampleDataList[Index].AddWeight(GridElement.Weights[Ind]*GridWeight); } } } /** Used to sort by Weight. */ struct FCompareFBlendSampleData { FORCEINLINE bool operator()( const FBlendSampleData& A, const FBlendSampleData& B ) const { return B.TotalWeight < A.TotalWeight; } }; OutSampleDataList.Sort( FCompareFBlendSampleData() ); // remove noisy ones int32 TotalSample = OutSampleDataList.Num(); float TotalWeight = 0.f; for (int32 I=0; I<TotalSample; ++I) { if (OutSampleDataList[I].TotalWeight < ZERO_ANIMWEIGHT_THRESH) { // cut anything in front of this OutSampleDataList.RemoveAt(I, TotalSample-I); break; } TotalWeight += OutSampleDataList[I].TotalWeight; } for (int32 I=0; I<OutSampleDataList.Num(); ++I) { // normalize to all weights OutSampleDataList[I].TotalWeight /= TotalWeight; } return (OutSampleDataList.Num()!=0); }
bool UBlendSpaceBase::GetSamplesFromBlendInput(const FVector &BlendInput, TArray<FBlendSampleData> & OutSampleDataList) const { TArray<FGridBlendSample, TInlineAllocator<4> >& RawGridSamples = FBlendSpaceScratchData::Get().RawGridSamples; check(!RawGridSamples.Num()); // this must be called non-recursively GetRawSamplesFromBlendInput(BlendInput, RawGridSamples); OutSampleDataList.Reset(); OutSampleDataList.Reserve(RawGridSamples.Num() * FEditorElement::MAX_VERTICES); // consolidate all samples for (int32 SampleNum=0; SampleNum<RawGridSamples.Num(); ++SampleNum) { FGridBlendSample& GridSample = RawGridSamples[SampleNum]; float GridWeight = GridSample.BlendWeight; FEditorElement& GridElement = GridSample.GridElement; for(int32 Ind = 0; Ind < GridElement.MAX_VERTICES; ++Ind) { const int32 SampleDataIndex = GridElement.Indices[Ind]; if(SampleDataIndex != INDEX_NONE) { int32 Index = OutSampleDataList.AddUnique(SampleDataIndex); OutSampleDataList[Index].AddWeight(GridElement.Weights[Ind]*GridWeight); OutSampleDataList[Index].Animation = SampleData[SampleDataIndex].Animation; } } } // go through merge down to first sample for (int32 Index1 = 0; Index1 < OutSampleDataList.Num(); ++Index1) { for (int32 Index2 = Index1 + 1; Index2 < OutSampleDataList.Num(); ++Index2) { // if they have sample sample, remove the Index2, and get out if (OutSampleDataList[Index1].Animation == OutSampleDataList[Index2].Animation) { // add weight OutSampleDataList[Index1].AddWeight(OutSampleDataList[Index2].GetWeight()); // as for time or previous time will be the master one(Index1) OutSampleDataList.RemoveAtSwap(Index2, 1, false); --Index2; } } } /** Used to sort by Weight. */ struct FCompareFBlendSampleData { FORCEINLINE bool operator()(const FBlendSampleData& A, const FBlendSampleData& B) const { return B.TotalWeight < A.TotalWeight; } }; OutSampleDataList.Sort(FCompareFBlendSampleData()); // remove noisy ones int32 TotalSample = OutSampleDataList.Num(); float TotalWeight = 0.f; for (int32 I=0; I<TotalSample; ++I) { if (OutSampleDataList[I].TotalWeight < ZERO_ANIMWEIGHT_THRESH) { // cut anything in front of this OutSampleDataList.RemoveAt(I, TotalSample-I, false); // we won't shrink here, that might screw up alloc optimization at a higher level, if not this is temp anyway break; } TotalWeight += OutSampleDataList[I].TotalWeight; } for (int32 I=0; I<OutSampleDataList.Num(); ++I) { // normalize to all weights OutSampleDataList[I].TotalWeight /= TotalWeight; } RawGridSamples.Reset(); return (OutSampleDataList.Num()!=0); }