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); } }
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; }
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)); }