Beispiel #1
0
void FLODCluster::SubtractCluster(const FLODCluster& Other)
{
	for(int32 ActorId=0; ActorId<Actors.Num(); ++ActorId)
	{
		if (Other.Actors.Contains(Actors[ActorId]))
		{
			Actors.RemoveAt(ActorId);
			--ActorId;
		}
	}

	TArray<AActor*> NewActors = Actors;
	Actors.Empty();
	// need to recalculate parameter
	if (NewActors.Num() == 0)
	{
		Invalidate();
	}
	else if (NewActors.Num() == 1)
	{
		Bound = FSphere(ForceInitToZero);
		AddActor(NewActors[0]);
		FillingFactor = 1.f;
		ClusterCost = FMath::Pow(Bound.W, 3) / FillingFactor;
	}
	else if (NewActors.Num() >= 2)
	{
		Bound = FSphere(ForceInit);

		FSphere Actor1Bound = AddActor(NewActors[0]);
		FSphere Actor2Bound = AddActor(NewActors[1]);

		// calculate new filling factor
		FillingFactor = CalculateFillingFactor(Actor1Bound, 1.f, Actor2Bound, 1.f);

		// if more actors, we add them manually
		for (int32 ActorId=2; ActorId<NewActors.Num(); ++ActorId)
		{
			// if not contained, it shouldn't be
			check (!Actors.Contains(NewActors[ActorId]));

			FSphere NewBound = AddActor(NewActors[ActorId]);
			FillingFactor = CalculateFillingFactor(NewBound, 1.f, Bound, FillingFactor);
			Bound += NewBound;
		}

		ClusterCost = FMath::Pow(Bound.W, 3) / FillingFactor;
	}
}
FSphere USpotLightComponent::GetBoundingSphere() const
{
	float ClampedInnerConeAngle = FMath::Clamp(InnerConeAngle,0.0f,89.0f) * (float)PI / 180.0f;
	float ClampedOuterConeAngle = FMath::Clamp(OuterConeAngle * (float)PI / 180.0f,ClampedInnerConeAngle + 0.001f,89.0f * (float)PI / 180.0f + 0.001f);

	float CosOuterCone = FMath::Cos(ClampedOuterConeAngle);

	// Use the law of cosines to find the distance to the furthest edge of the spotlight cone from a position that is halfway down the spotlight direction
	const float BoundsRadius = FMath::Sqrt(1.25f * AttenuationRadius * AttenuationRadius - AttenuationRadius * AttenuationRadius * CosOuterCone);
	return FSphere(ComponentToWorld.GetLocation() + .5f * GetDirection() * AttenuationRadius, BoundsRadius);
}
void PrefilterPlanarReflection(FRHICommandListImmediate& RHICmdList, FViewInfo& View, const FPlanarReflectionSceneProxy* ReflectionSceneProxy, const FRenderTarget* Target)
{
	FTextureRHIParamRef SceneColorInput = FSceneRenderTargets::Get(RHICmdList).GetSceneColorTexture();

	if(View.FeatureLevel >= ERHIFeatureLevel::SM4)
	{
		// Note: null velocity buffer, so dynamic object temporal AA will not be correct
		TRefCountPtr<IPooledRenderTarget> VelocityRT;
		TRefCountPtr<IPooledRenderTarget> FilteredSceneColor;
		GPostProcessing.ProcessPlanarReflection(RHICmdList, View, VelocityRT, FilteredSceneColor);

		if (FilteredSceneColor)
		{
			SceneColorInput = FilteredSceneColor->GetRenderTargetItem().ShaderResourceTexture;
		}
	}

	{
		SCOPED_DRAW_EVENT(RHICmdList, PrefilterPlanarReflection);

		FRHIRenderTargetView ColorView(Target->GetRenderTargetTexture(), 0, -1, ERenderTargetLoadAction::ENoAction, ERenderTargetStoreAction::EStore);
		FRHISetRenderTargetsInfo Info(1, &ColorView, FRHIDepthRenderTargetView());
		RHICmdList.SetRenderTargetsAndClear(Info);

		RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f);

		RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
		RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI());
		RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());

		TShaderMapRef<TDeferredLightVS<false> > VertexShader(View.ShaderMap);
		TShaderMapRef<FPrefilterPlanarReflectionPS<bEnablePlanarReflectionPrefilter> > PixelShader(View.ShaderMap);

		static FGlobalBoundShaderState BoundShaderState;
		SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

		PixelShader->SetParameters(RHICmdList, View, ReflectionSceneProxy, SceneColorInput);
		VertexShader->SetSimpleLightParameters(RHICmdList, View, FSphere(0));

		DrawRectangle(
			RHICmdList,
			0, 0,
			View.ViewRect.Width(), View.ViewRect.Height(),
			View.ViewRect.Min.X, View.ViewRect.Min.Y,
			View.ViewRect.Width(), View.ViewRect.Height(),
			View.ViewRect.Size(),
			FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(),
			*VertexShader,
			EDRF_UseTriangleOptimization);
	}
}
Beispiel #4
0
FSphere FLODCluster::AddActor(AActor* NewActor)
{
	bValid = true;
	ensure (Actors.Contains(NewActor) == false);
	Actors.Add(NewActor);
	FVector Origin, Extent;

	NewActor->GetActorBounds(false, Origin, Extent);

	// scale 0.01 (change to meter from centimeter) QQ Extens.GetSize	
	FSphere NewBound = FSphere(Origin*CM_TO_METER, Extent.Size()*CM_TO_METER);
	Bound += NewBound;

	return NewBound;
}
Beispiel #5
0
FSphere::FSphere(const FVector* Pts, int32 Count)
	: Center(0, 0, 0)
	, W(0)
{
	if (Count)
	{
		const FBox Box(Pts, Count);

		*this = FSphere((Box.Min + Box.Max) / 2, 0);

		for (int32 i = 0; i < Count; i++)
		{
			const float Dist = FVector::DistSquared(Pts[i], Center);

			if (Dist > W)
			{
				W = Dist;
			}
		}

		W = FMath::Sqrt(W) * 1.001f;
	}
}
	virtual FSphere GetBoundingSphere() const override
	{
		// Use the law of cosines to find the distance to the furthest edge of the spotlight cone from a position that is halfway down the spotlight direction
		const float BoundsRadius = FMath::Sqrt(1.25f * Radius * Radius - Radius * Radius * CosOuterCone);
		return FSphere(GetOrigin() + .5f * GetDirection() * Radius, BoundsRadius);
	}
void FEQSSceneProxy::CollectEQSData(const FEnvQueryResult* ResultItems, const FEnvQueryInstance* QueryInstance, float HighlightRangePct, bool ShouldDrawFailedItems, TArray<FSphere>& Spheres, TArray<FText3d>& Texts, TArray<EQSDebug::FDebugHelper>& DebugItems)
{
	if (ResultItems == NULL)
	{
		if (QueryInstance == NULL)
		{
			return;
		}
		else
		{
			ResultItems = QueryInstance;
		}
	}

	// using "mid-results" requires manual normalization
	const bool bUseMidResults = QueryInstance && (QueryInstance->Items.Num() < QueryInstance->DebugData.DebugItems.Num());
	// no point in checking if QueryInstance != null since bUseMidResults == true guarantees that, PVS-Studio doesn't
	// understand that invariant though, and we need to disable V595:
	const TArray<FEnvQueryItem>& Items = bUseMidResults ? QueryInstance->DebugData.DebugItems : ResultItems->Items; //-V595
	const TArray<uint8>& RawData = bUseMidResults ? QueryInstance->DebugData.RawData : ResultItems->RawData;
	const int32 ItemCountLimit = FMath::Clamp(Items.Num(), 0, EQSMaxItemsDrawn);
	const bool bNoTestsPerformed = QueryInstance != NULL && QueryInstance->CurrentTest <= 0;
	
	const bool bSingleItemResult = QueryInstance != NULL && QueryInstance->DebugData.bSingleItemResult;

	float MinScore = 0.f;
	float MaxScore = -BIG_NUMBER;
	if (bUseMidResults || HighlightRangePct < 1.0f)
	{
		const FEnvQueryItem* ItemInfo = Items.GetData();
		for (int32 ItemIndex = 0; ItemIndex < Items.Num(); ItemIndex++, ItemInfo++)
		{
			if (ItemInfo->IsValid())
			{
				MinScore = FMath::Min(MinScore, ItemInfo->Score);
				MaxScore = FMath::Max(MaxScore, ItemInfo->Score);
			}
		}
	}
	
	const float ScoreNormalizer = bUseMidResults && (MaxScore != MinScore) ? 1.f / (MaxScore - MinScore) : 1.f;
	const float HighlightThreshold = (HighlightRangePct < 1.0f) ? (MaxScore * HighlightRangePct) : FLT_MAX;

	if (bSingleItemResult == false)
	{
		for (int32 ItemIndex = 0; ItemIndex < ItemCountLimit; ++ItemIndex)
		{
			if (Items[ItemIndex].IsValid())
			{
				const float Score = bNoTestsPerformed ? 1 : Items[ItemIndex].Score * ScoreNormalizer;
				const bool bLowRadius = (HighlightThreshold < FLT_MAX) && (bNoTestsPerformed || (Items[ItemIndex].Score < HighlightThreshold));
				const float Radius = ItemDrawRadius.X * (bLowRadius ? 0.2f : 1.0f);
				const FVector Loc = FEQSRenderingHelper::ExtractLocation(ResultItems->ItemType, RawData, Items, ItemIndex);
				Spheres.Add(FSphere(Radius, Loc, bNoTestsPerformed == false
					? FLinearColor(FColor::MakeRedToGreenColorFromScalar(Score)) 
					: FLinearColor(0.2, 1.0, 1.0, 1)));

				DebugItems.Add(EQSDebug::FDebugHelper(Loc, Radius));

				const FString Label = bNoTestsPerformed ? TEXT("") : FString::Printf(TEXT("%.2f"), Score);
				Texts.Add(FText3d(Label, Loc, FLinearColor::White));
			}
		}
	}
	else if (ItemCountLimit > 0)
	{
		if (Items[0].IsValid())
		{
			const float Score = Items[0].Score * ScoreNormalizer;
			const bool bLowRadius = false;
			const float Radius = ItemDrawRadius.X * (bLowRadius ? 0.2f : 1.0f);
			const FVector Loc = FEQSRenderingHelper::ExtractLocation(ResultItems->ItemType, RawData, Items, 0);
			Spheres.Add(FSphere(Radius, Loc, FLinearColor(0.0, 1.0, 0.12, 1)));

			DebugItems.Add(EQSDebug::FDebugHelper(Loc, Radius));

			const FString Label = FString::Printf(TEXT("Winner %.2f"), Score);
			Texts.Add(FText3d(Label, Loc, FLinearColor::White));
		}

		for (int32 ItemIndex = 1; ItemIndex < ItemCountLimit; ++ItemIndex)
		{
			if (Items[ItemIndex].IsValid())
			{
				const float Score = bNoTestsPerformed ? 1 : Items[ItemIndex].Score * ScoreNormalizer;
				const bool bLowRadius = (HighlightThreshold < FLT_MAX) && (bNoTestsPerformed || (Items[ItemIndex].Score < HighlightThreshold));
				const float Radius = ItemDrawRadius.X * (bLowRadius ? 0.2f : 1.0f);
				const FVector Loc = FEQSRenderingHelper::ExtractLocation(ResultItems->ItemType, RawData, Items, ItemIndex);
				Spheres.Add(FSphere(Radius, Loc, FLinearColor(0.0, 0.2, 0.025, 1)));

				DebugItems.Add(EQSDebug::FDebugHelper(Loc, Radius));
				
				const FString Label = bNoTestsPerformed ? TEXT("") : FString::Printf(TEXT("%.2f"), Score);
				Texts.Add(FText3d(Label, Loc, FLinearColor::White));
			}
		}
	}

	if (ShouldDrawFailedItems && QueryInstance)
	{
		const FEQSQueryDebugData& InstanceDebugData = QueryInstance->DebugData;
		const TArray<FEnvQueryItem>& DebugQueryItems = InstanceDebugData.DebugItems;
		const TArray<FEnvQueryItemDetails>& Details = InstanceDebugData.DebugItemDetails;

		const int32 DebugItemCountLimit = DebugQueryItems.Num() == Details.Num() ? FMath::Clamp(DebugQueryItems.Num(), 0, EQSMaxItemsDrawn) : 0;

		for (int32 ItemIndex = 0; ItemIndex < DebugItemCountLimit; ++ItemIndex)
		{
			if (DebugQueryItems[ItemIndex].IsValid())
			{
				continue;
			}

			const float Score = bNoTestsPerformed ? 1 : Items[ItemIndex].Score * ScoreNormalizer;
			const bool bLowRadius = (HighlightThreshold < FLT_MAX) && (bNoTestsPerformed || (Items[ItemIndex].Score < HighlightThreshold));
			const float Radius = ItemDrawRadius.X * (bLowRadius ? 0.2f : 1.0f);
			const FVector Loc = FEQSRenderingHelper::ExtractLocation(QueryInstance->ItemType, InstanceDebugData.RawData, DebugQueryItems, ItemIndex);
			Spheres.Add(FSphere(Radius, Loc, FLinearColor(0.0, 0.0, 0.6, 0.6)));

			auto& DebugHelper = DebugItems[DebugItems.Add(EQSDebug::FDebugHelper(Loc, Radius))];
			DebugHelper.AdditionalInformation = Details[ItemIndex].FailedDescription;
			if (Details[ItemIndex].FailedTestIndex != INDEX_NONE)
			{
				DebugHelper.FailedTestIndex = Details[ItemIndex].FailedTestIndex;
				DebugHelper.FailedScore = Details[ItemIndex].TestResults[DebugHelper.FailedTestIndex];

				const FString Label = InstanceDebugData.PerformedTestNames[DebugHelper.FailedTestIndex] + FString::Printf(TEXT("(%d)"), DebugHelper.FailedTestIndex);
				Texts.Add(FText3d(Label, Loc, FLinearColor::White));
			}
		}
	}
}
FBoxSphereBounds UTangoPointsComponent::CalcBounds(const FTransform & LocalToWorld) const
{
	return FBoxSphereBounds(FSphere(LocalToWorld.GetLocation(), 100));
}