EConvertQueryResult AddSweepResults(bool& OutHasValidBlockingHit, const UWorld* World, int32 NumHits, PxSweepHit* Hits, float CheckLength, const PxFilterData& QueryFilter, TArray<FHitResult>& OutHits, const FVector& StartLoc, const FVector& EndLoc, const PxGeometry& Geom, const PxTransform& QueryTM, float MaxDistance, bool bReturnFaceIndex, bool bReturnPhysMat)
{
	OutHits.Reserve(OutHits.Num() + NumHits);
	EConvertQueryResult ConvertResult = EConvertQueryResult::Valid;
	bool bHadBlockingHit = false;
	const PxVec3 PDir = U2PVector((EndLoc - StartLoc).GetSafeNormal());

	for(int32 i=0; i<NumHits; i++)
	{
		PxSweepHit& PHit = Hits[i];
		checkSlow(PHit.flags & PxHitFlag::eDISTANCE);
		if(PHit.distance <= MaxDistance)
		{
			PHit.faceIndex = FindFaceIndex(PHit, PDir);

			FHitResult& NewResult = OutHits[OutHits.AddDefaulted()];
			if (ConvertQueryImpactHit(World, PHit, NewResult, CheckLength, QueryFilter, StartLoc, EndLoc, &Geom, QueryTM, bReturnFaceIndex, bReturnPhysMat) == EConvertQueryResult::Valid)
			{
				bHadBlockingHit |= NewResult.bBlockingHit;
			}
			else
			{
				// Reject invalid result (this should be rare). Remove from the results.
				OutHits.Pop(/*bAllowShrinking=*/ false);
				ConvertResult = EConvertQueryResult::Invalid;
			}
			
		}
	}

	// Sort results from first to last hit
	OutHits.Sort( FCompareFHitResultTime() );
	OutHasValidBlockingHit = bHadBlockingHit;
	return ConvertResult;
}
void ConvertRaycastResults(const UWorld* World, int32 NumHits, PxRaycastHit* Hits, float CheckLength, const PxFilterData& QueryFilter, TArray<FHitResult>& OutHits, const FVector& StartLoc, const FVector& EndLoc, bool bReturnFaceIndex, bool bReturnPhysMat)
{
	OutHits.Reserve(OutHits.Num() + NumHits);

	PxTransform PStartTM(U2PVector(StartLoc));
	for(int32 i=0; i<NumHits; i++)
	{
		FHitResult& NewResult = OutHits[OutHits.AddDefaulted()];
		const PxRaycastHit& PHit = Hits[i];

		ConvertQueryImpactHit(World, PHit, NewResult, CheckLength, QueryFilter, StartLoc, EndLoc, NULL, PStartTM, bReturnFaceIndex, bReturnPhysMat);
	}

	// Sort results from first to last hit
	OutHits.Sort( FCompareFHitResultTime() );
}
void ConvertRaycastResults(int32 NumHits, PxRaycastHit* Hits, float CheckLength, const PxFilterData& QueryFilter, TArray<FHitResult>& OutHits, const FVector& StartLoc, const FVector& EndLoc, bool bReturnFaceIndex, bool bReturnPhysMat)
{
	PxTransform PStartTM(U2PVector(StartLoc));
	for(int32 i=0; i<NumHits; i++)
	{
		FHitResult NewResult(ForceInit);
		const PxRaycastHit& PHit = Hits[i];

		ConvertQueryImpactHit(PHit, NewResult, CheckLength, QueryFilter, StartLoc, EndLoc, NULL, PStartTM, bReturnFaceIndex, bReturnPhysMat);

		OutHits.Add(NewResult);
	}

	// Sort results from first to last hit
	OutHits.Sort( FCompareFHitResultTime() );
}
bool AddSweepResults(const UWorld* World, int32 NumHits, const PxSweepHit* Hits, float CheckLength, const PxFilterData& QueryFilter, TArray<FHitResult>& OutHits, const FVector& StartLoc, const FVector& EndLoc, const PxGeometry& Geom, const PxTransform& QueryTM, float MaxDistance, bool bReturnPhysMat)
{
	OutHits.Reserve(OutHits.Num() + NumHits);
	bool bHadBlockingHit = false;

	for(int32 i=0; i<NumHits; i++)
	{
		const PxSweepHit& PHit = Hits[i];
		checkSlow(PHit.flags & PxHitFlag::eDISTANCE);
		if(PHit.distance <= MaxDistance)
		{
			FHitResult& NewResult = OutHits[OutHits.AddDefaulted()];
			ConvertQueryImpactHit(World, PHit, NewResult, CheckLength, QueryFilter, StartLoc, EndLoc, &Geom, QueryTM, false, bReturnPhysMat);
			bHadBlockingHit |= NewResult.bBlockingHit;
		}
	}

	// Sort results from first to last hit
	OutHits.Sort( FCompareFHitResultTime() );
	return bHadBlockingHit;
}
bool AddSweepResults(int32 NumHits, PxSweepHit* Hits, float CheckLength, const PxFilterData& QueryFilter, TArray<FHitResult>& OutHits, const FVector& StartLoc, const FVector& EndLoc, const PxGeometry& Geom, const PxTransform& QueryTM, float MaxDistance, bool bReturnPhysMat)
{
	OutHits.Reserve(NumHits);
	bool bHadBlockingHit = false;

	for(int32 i=0; i<NumHits; i++)
	{
		const PxSweepHit& PHit = Hits[i];
		if(PHit.distance <= MaxDistance)
		{
			FHitResult NewResult(ForceInit);
			ConvertQueryImpactHit(PHit, NewResult, CheckLength, QueryFilter, StartLoc, EndLoc, &Geom, QueryTM, false, bReturnPhysMat);
			bHadBlockingHit |= NewResult.bBlockingHit;
			OutHits.Add(NewResult);
		}
	}

	// Sort results from first to last hit
	OutHits.Sort( FCompareFHitResultTime() );
	return bHadBlockingHit;
}
EConvertQueryResult ConvertRaycastResults(bool& OutHasValidBlockingHit, const UWorld* World, int32 NumHits, PxRaycastHit* Hits, float CheckLength, const PxFilterData& QueryFilter, TArray<FHitResult>& OutHits, const FVector& StartLoc, const FVector& EndLoc, bool bReturnFaceIndex, bool bReturnPhysMat)
{
#if PLATFORM_LINUX	// to narrow down OR-24947
	_Pragma("clang optimize off");
#endif // PLATFORM_LINUX

	OutHits.Reserve(OutHits.Num() + NumHits);
	EConvertQueryResult ConvertResult = EConvertQueryResult::Valid;
	bool bHadBlockingHit = false;

	PxTransform PStartTM(U2PVector(StartLoc));
	for(int32 i=0; i<NumHits; i++)
	{
		FHitResult& NewResult = OutHits[OutHits.Emplace()];
		const PxRaycastHit& PHit = Hits[i];

		if (ConvertQueryImpactHit(World, PHit, NewResult, CheckLength, QueryFilter, StartLoc, EndLoc, NULL, PStartTM, bReturnFaceIndex, bReturnPhysMat) == EConvertQueryResult::Valid)
		{
			bHadBlockingHit |= NewResult.bBlockingHit;
		}
		else
		{
			// Reject invalid result (this should be rare). Remove from the results.
			OutHits.Pop(/*bAllowShrinking=*/ false);
			ConvertResult = EConvertQueryResult::Invalid;
		}
	}

	// Sort results from first to last hit
	OutHits.Sort( FCompareFHitResultTime() );
	OutHasValidBlockingHit = bHadBlockingHit;
	return ConvertResult;

#if PLATFORM_LINUX	// to narrow down OR-24947
	_Pragma("clang optimize on");
#endif // PLATFORM_LINUX
}