// Creates child/parent relationship between the nodes static void LinkToParents(TMultiMap<UObject*, FRefGraphItem*>& InputGraphNodeList, FRefGraphItem* NodeToLink) { for (auto It = InputGraphNodeList.CreateConstIterator(); It; ++It) { if (It.Value()->Link.ReferencedObj == NodeToLink->Link.ReferencedBy) { It.Value()->Children.Push(NodeToLink); NodeToLink->Parents.Push(It.Value()); } } }
void FReferenceChainSearch::BuildRefGraph() { UE_LOG(LogReferenceChain, Log, TEXT("Generating reference graph ...")); bool bContinue = true; TMultiMap<UObject*, FRefGraphItem*> GraphNodes; // Create the first graph-nodes referencing the target object for (FRawObjectIterator It;It;++It) { UObject* Obj = *It; TArray<FReferenceChainLink>& RefList = ReferenceMap.FindChecked(Obj); for (int32 i=0; i < RefList.Num(); ++i) { if (RefList[i].ReferencedObj == ObjectToFind) { FRefGraphItem* Node = new FRefGraphItem(); Node->Link = RefList[i]; GraphNodes.Add(Node->Link.ReferencedBy, Node); RefList[i].ReferenceType = EReferenceType::Invalid; } } } int32 Level = 0; UE_LOG(LogReferenceChain, Log, TEXT("Level 0 has %d nodes ..."), GraphNodes.Num()); while(bContinue) { int32 AddedNodes = 0; TArray<FRefGraphItem*> NewGraphNodes; for (FRawObjectIterator It;It;++It) { UObject* Obj = *It; TArray<FReferenceChainLink>& RefList = ReferenceMap.FindChecked(Obj); for (int32 i=0; i < RefList.Num(); ++i) { if (RefList[i].ReferenceType == EReferenceType::Invalid || RefList[i].ReferencedObj->HasAnyFlags(GARBAGE_COLLECTION_KEEPFLAGS | RF_RootSet)) // references to rooted objects are not important { continue; } TArray<FRefGraphItem*> RefNodes; if (FindReferencedGraphNodes(GraphNodes, RefList[i].ReferencedObj, RefNodes) > 0) { FRefGraphItem* Node = FindNode(GraphNodes, RefList[i].ReferencedBy, RefList[i].ReferencedObj); if (Node == NULL) { Node = new FRefGraphItem(); Node->Link = RefList[i]; NewGraphNodes.Push(Node); } for (int32 j=0; j < RefNodes.Num(); ++j) { Node->Children.Push(RefNodes[j]); RefNodes[j]->Parents.Push(Node); } ++AddedNodes; RefList[i].ReferenceType = EReferenceType::Invalid; } } } Level++; UE_LOG(LogReferenceChain, Log, TEXT("Level %d added %d nodes ..."), Level, NewGraphNodes.Num()); for (int32 i = 0; i < NewGraphNodes.Num(); ++i) { GraphNodes.Add(NewGraphNodes[i]->Link.ReferencedBy, NewGraphNodes[i]); } NewGraphNodes.Empty(NewGraphNodes.Num()); bContinue = AddedNodes > 0; } TArray<FReferenceChain> Chains; UE_LOG(LogReferenceChain, Log, TEXT("Generating reference chains ...")); for (auto It = GraphNodes.CreateConstIterator(); It; ++It) { FRefGraphItem* Node = It.Value(); if (Node->Link.ReferencedBy->HasAnyFlags(GARBAGE_COLLECTION_KEEPFLAGS | RF_RootSet)) { FReferenceChain CurChain; CreateReferenceChain(Node, CurChain, Chains, ObjectToFind, Level); } } for (int32 i=0; i < Chains.Num(); ++i) { InsertReferenceChain(Chains[i]); } }
void FAudioComponentVisualizer::DrawVisualization( const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI ) { if(View->Family->EngineShowFlags.AudioRadius) { const UAudioComponent* AudioComp = Cast<const UAudioComponent>(Component); if(AudioComp != NULL) { const FTransform& Transform = AudioComp->ComponentToWorld; TMultiMap<EAttenuationShape::Type, FAttenuationSettings::AttenuationShapeDetails> ShapeDetailsMap; AudioComp->CollectAttenuationShapesForVisualization(ShapeDetailsMap); FVector Translation = Transform.GetTranslation(); FVector UnitXAxis = Transform.GetUnitAxis( EAxis::X ); FVector UnitYAxis = Transform.GetUnitAxis( EAxis::Y ); FVector UnitZAxis = Transform.GetUnitAxis( EAxis::Z ); for ( auto It = ShapeDetailsMap.CreateConstIterator(); It; ++It ) { FColor AudioOuterRadiusColor(255, 153, 0); FColor AudioInnerRadiusColor(216, 130, 0); const FAttenuationSettings::AttenuationShapeDetails& ShapeDetails = It.Value(); switch(It.Key()) { case EAttenuationShape::Box: if (ShapeDetails.Falloff > 0.f) { DrawOrientedWireBox( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, ShapeDetails.Extents + FVector(ShapeDetails.Falloff), AudioOuterRadiusColor, SDPG_World); DrawOrientedWireBox( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, ShapeDetails.Extents, AudioInnerRadiusColor, SDPG_World); } else { DrawOrientedWireBox( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, ShapeDetails.Extents, AudioOuterRadiusColor, SDPG_World); } break; case EAttenuationShape::Capsule: if (ShapeDetails.Falloff > 0.f) { DrawWireCapsule( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, AudioOuterRadiusColor, ShapeDetails.Extents.Y + ShapeDetails.Falloff, ShapeDetails.Extents.X + ShapeDetails.Falloff, 25, SDPG_World); DrawWireCapsule( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, AudioInnerRadiusColor, ShapeDetails.Extents.Y, ShapeDetails.Extents.X, 25, SDPG_World); } else { DrawWireCapsule( PDI, Translation, UnitXAxis, UnitYAxis, UnitZAxis, AudioOuterRadiusColor, ShapeDetails.Extents.Y, ShapeDetails.Extents.X, 25, SDPG_World); } break; case EAttenuationShape::Cone: { FTransform Origin = Transform; Origin.SetScale3D(FVector(1.f)); Origin.SetTranslation(Translation - (UnitXAxis * ShapeDetails.ConeOffset)); if (ShapeDetails.Falloff > 0.f || ShapeDetails.Extents.Z > 0.f) { float ConeRadius = ShapeDetails.Extents.X + ShapeDetails.Falloff + ShapeDetails.ConeOffset; float ConeAngle = ShapeDetails.Extents.Y + ShapeDetails.Extents.Z; DrawWireSphereCappedCone(PDI, Origin, ConeRadius, ConeAngle, 16, 4, 10, AudioOuterRadiusColor, SDPG_World); ConeRadius = ShapeDetails.Extents.X + ShapeDetails.ConeOffset; ConeAngle = ShapeDetails.Extents.Y; DrawWireSphereCappedCone(PDI, Origin, ConeRadius, ConeAngle, 16, 4, 10, AudioInnerRadiusColor, SDPG_World ); } else { const float ConeRadius = ShapeDetails.Extents.X + ShapeDetails.ConeOffset; const float ConeAngle = ShapeDetails.Extents.Y; DrawWireSphereCappedCone(PDI, Origin, ConeRadius, ConeAngle, 16, 4, 10, AudioOuterRadiusColor, SDPG_World ); } } break; case EAttenuationShape::Sphere: if (ShapeDetails.Falloff > 0.f) { DrawWireSphereAutoSides(PDI, Translation, AudioOuterRadiusColor, ShapeDetails.Extents.X + ShapeDetails.Falloff, SDPG_World); DrawWireSphereAutoSides(PDI, Translation, AudioInnerRadiusColor, ShapeDetails.Extents.X, SDPG_World); } else { DrawWireSphereAutoSides(PDI, Translation, AudioOuterRadiusColor, ShapeDetails.Extents.X, SDPG_World); } break; default: check(false); } } } } }