Files
UnrealEngineUWP/Engine/Source/Editor/AudioEditor/Private/SoundClassGraph.cpp
James Brinkerhoff 0f37066e3e Copying //UE4/Ocean-Staging to //UE4/Dev-Main (Source: //Ocean/Main @ 3355692)
#lockdown Nick.Penwarden

==========================
MAJOR FEATURES + CHANGES
==========================

Change 3348195 on 2017/03/15 by James.Brinkerhoff

	Hotfix from CL 3347729 for variable shadow warning caused by CL 3347393

Change 3347935 on 2017/03/15 by James.Brinkerhoff

	Hotfix from CL 3347393 for a runtime asset crash

Change 3340537 on 2017/03/09 by James.Brinkerhoff

	Hotfix from CL 3338679 for arrow keys not working to navigate between elements in the details panel

Change 3335755 on 2017/03/07 by Ben.Marsh

	Pass bCreateStubIPA into PrepForUATPackageOrDeploy rather than setting it through a global configuration object (which is no longer accessible).

Change 3334652 on 2017/03/06 by James.Brinkerhoff

	Merging //UE4/Ocean-Staging to //Ocean/Main @ CL 3331740

Change 3332441 on 2017/03/03 by James.Brinkerhoff

	Hotfix from CL 3296668 for assert when creating memory reports
	#jira OCN-6087: [CRASH] Crash after entering the memreport command into the command line.

Change 3318933 on 2017/02/23 by Allan.Bentham

	Temp workaround for iOS metal sRGB capable render targets sRGB correcting twice.

Change 3314064 on 2017/02/21 by Richard.Fawcett

	Implement randomized manifest filenames for Ocean.

Change 3313139 on 2017/02/20 by James.Brinkerhoff

	Hotfix from CL 3262052 for UE-40782 Put back the skinxx workflow for the staticmesh

Change 3292678 on 2017/02/08 by Brian.Zaugg

	Back out changelist 3292455

Change 3292455 on 2017/02/08 by Brian.Zaugg

	Back out changelist 3292268

Change 3292268 on 2017/02/08 by Allan.Bentham

	Restore DestStride output value when locking compressed textures.

Change 3288925 on 2017/02/06 by Brian.Zaugg

	Change this error from a check to an error log: "Loading non-streamed mips from an external bulk file.  This is not desireable."

Change 3288441 on 2017/02/06 by James.Brinkerhoff

	Hotfix from CL 3255451 for UE-40384: Reference Viewer comment text is difficult to read
	#jira OCN-6059: CLONE - Comment boxes are turning opaque when the game is running

Change 3285501 on 2017/02/03 by Allan.Bentham

	Fix  for ring buffer not allocating sufficient space for large requests.

Change 3280062 on 2017/01/31 by Max.Chen

	Sequencer: Find object in any package. This fixes an issue where bound objects can't be found.

	#jira UE-39459

Change 3279375 on 2017/01/31 by Brian.Zaugg

	Increase TaskGraph thread stack size for non-shipping builds to prevent stack overflow on iOS.

Change 3279366 on 2017/01/31 by Brian.Zaugg

	Fix for iOS virtual keyboard.

Change 3275965 on 2017/01/27 by Max.Chen

	Sequencer: Only reset persistent evaluation data when the sequence has changed
	  - This ensures that we don't destroy persistent data that is assumed to still exist (i.e. it was created in ::Setup) from the same sequence

	Copy from Release-4.15

	#jira UE-40234

Change 3275963 on 2017/01/27 by Max.Chen

	Sequencer: Fixed crash caused by lingering persistent evaluation data

	Copy from Release-4.15

	#jira UE-40064

Change 3275962 on 2017/01/27 by Max.Chen

	Sequencer: Evaluation templates are now only fully rebuilt in PIE, and will not re-cycle track identifiers
	  - This addresses issues with newly compiled tracks recycling the persistent data of old stale tracks.
	  - This commit also ensures we don't fully rebuild templates in the editor when in Sequencer

	Copy from Release-4.15

	#jira UE-39882

Change 3275523 on 2017/01/27 by James.Brinkerhoff

	Fix issue with automation tool caused by a bad resolve

Change 3274292 on 2017/01/26 by James.Brinkerhoff

	Merging //UE4/Ocean-Staging to //Ocean/Main @ CL 3269883

Change 3252898 on 2017/01/10 by James.Brinkerhoff

	Hotfix from CL 3187276 for UE-39071: Crash on adding Actor Reference property to a Struct

Change 3248463 on 2017/01/05 by Aaron.McLeran

	Implementing UE-39421 fix into Ocean

Change 3247933 on 2017/01/05 by James.Brinkerhoff

	Hotfix from CL 3246828 for UE-39249: Particle effects only render in one eye for VR

Change 3242274 on 2016/12/21 by James.Brinkerhoff

	Hotfix from CL 3209235 for UE-16688 - Selection and selection highlight doesn't work on child actors

Change 3242273 on 2016/12/21 by James.Brinkerhoff

	Hotfix from CL 3209232 for making the function GetComponents optionally include components in child actors
	Also fixed a circular dependency due to the hotfix (already applied in UE4 Main)

Change 3240035 on 2016/12/19 by Jaren.Peterson

	MovieSceneEventTemplate - Renamed FEventData to FMovieSceneEventData to eliminate confusion and clear up a crash occuring in Ocean debug builds.

Change 3236490 on 2016/12/15 by Chad.Garyet

	Updating packaged build to not make a stub.  This was stopping all icons from making it into the .ipa and messing up the resolution settings.
	also cleaned up the local staging directories.

Change 3231487 on 2016/12/12 by Brian.Zaugg

	Maintain aspect ratio when render target is clamped.

Change 3229050 on 2016/12/09 by Brian.Zaugg

	#ocn - Hotfix from CL 3218104.  Fixes code signing errors related to iCloud support.

Change 3225632 on 2016/12/07 by Brian.Zaugg

	New Chair Entertainment Group iOS Distribution certificate .p12.

Change 3224015 on 2016/12/06 by Brian.Zaugg

	#ocn - Hotfix from CL 3223546 fixes iOS audio crash after last merge from main.

Change 3221665 on 2016/12/05 by James.Brinkerhoff

	Merging hotfixes from //UE4/Ocean-Staging to //Ocean/Main
	Hotfix from CL 3216832 for non-unity build failures
	Hotfix from CL 3217564 for fixing the FixDylib script being run on too many modules. Mac build farm is oversaturated right now.

Change 3217759 on 2016/12/01 by James.Brinkerhoff

	Merging //UE4/Ocean-Staging to //Ocean/Main @ 3215855

Change 3214085 on 2016/11/29 by Casey.Spencer

	Removed logic in K2Node_BaseAsyncTask that excluded properties defined on super classes. Check with engine team prior to making change.

[CL 3359832 by James Brinkerhoff in Main branch]
2017-03-23 02:04:59 -04:00

307 lines
8.3 KiB
C++

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
/////////////////////////////////////////////////////
// USoundClassGraph
#include "SoundClassGraph/SoundClassGraph.h"
#include "UObject/Package.h"
#include "SoundClassGraph/SoundClassGraphNode.h"
#include "GraphEditor.h"
#include "Sound/SoundClass.h"
class FSoundClassAudioEditor : public ISoundClassAudioEditor
{
public:
void RefreshGraphLinks(UEdGraph* SoundClassGraph) override
{
CastChecked<USoundClassGraph>(SoundClassGraph)->RefreshGraphLinks();
}
};
USoundClassGraph::USoundClassGraph(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, RootSoundClass(NULL)
{
if (!USoundClass::GetSoundClassAudioEditor().IsValid())
{
USoundClass::SetSoundClassAudioEditor(TSharedPtr<ISoundClassAudioEditor>(new FSoundClassAudioEditor()));
}
}
void USoundClassGraph::SetRootSoundClass(USoundClass* InSoundClass)
{
RootSoundClass = InSoundClass;
}
USoundClass* USoundClassGraph::GetRootSoundClass() const
{
return RootSoundClass;
}
void USoundClassGraph::RebuildGraph()
{
check(RootSoundClass);
// Don't allow initial graph rebuild to affect package dirty state; remember current state...
UPackage* Package = GetOutermost();
const bool bIsDirty = Package->IsDirty();
Modify();
RemoveAllNodes();
ConstructNodes(RootSoundClass, 0, 0);
NotifyGraphChanged();
// ...and restore it
Package->SetDirtyFlag(bIsDirty);
}
void USoundClassGraph::AddDroppedSoundClasses(const TArray<USoundClass*>& SoundClasses, int32 NodePosX, int32 NodePosY)
{
Modify();
for (int32 ClassIndex = 0; ClassIndex < SoundClasses.Num(); ClassIndex++)
{
NodePosY += ConstructNodes(SoundClasses[ClassIndex], NodePosX, NodePosY);
}
NotifyGraphChanged();
}
void USoundClassGraph::AddNewSoundClass(UEdGraphPin* FromPin, class USoundClass* SoundClass, int32 NodePosX, int32 NodePosY, bool bSelectNewNode/* = true*/)
{
Modify();
USoundClassGraphNode* GraphNode = CreateNode(SoundClass, NodePosX, NodePosY, bSelectNewNode);
GraphNode->AutowireNewNode(FromPin);
NotifyGraphChanged();
}
bool USoundClassGraph::IsClassDisplayed(USoundClass* SoundClass) const
{
return FindExistingNode(SoundClass) != NULL;
}
void USoundClassGraph::LinkSoundClasses()
{
for (int32 NodeIndex = 0; NodeIndex < Nodes.Num(); NodeIndex++)
{
USoundClassGraphNode* Node = CastChecked<USoundClassGraphNode>(Nodes[NodeIndex]);
if (!Node->CheckRepresentsSoundClass())
{
Node->SoundClass->Modify();
// remove parents of existing children
for (int32 ChildIndex = 0; ChildIndex < Node->SoundClass->ChildClasses.Num(); ChildIndex++)
{
USoundClass* ChildClass = Node->SoundClass->ChildClasses[ChildIndex];
if (ChildClass)
{
ChildClass->Modify();
ChildClass->ParentClass = NULL;
}
}
Node->SoundClass->ChildClasses.Empty();
UEdGraphPin* ChildPin = Node->GetChildPin();
for (int32 ChildIndex = 0; ChildIndex < ChildPin->LinkedTo.Num(); ChildIndex++)
{
USoundClassGraphNode* ChildNode = CastChecked<USoundClassGraphNode>(ChildPin->LinkedTo[ChildIndex]->GetOwningNode());
Node->SoundClass->ChildClasses.Add(ChildNode->SoundClass);
ChildNode->SoundClass->SetParentClass(Node->SoundClass);
}
Node->SoundClass->PostEditChange();
Node->SoundClass->MarkPackageDirty();
}
}
RootSoundClass->RefreshAllGraphs(true);
}
void USoundClassGraph::RefreshGraphLinks()
{
Modify();
for (int32 NodeIndex = 0; NodeIndex < Nodes.Num(); NodeIndex++)
{
USoundClassGraphNode* Node = CastChecked<USoundClassGraphNode>(Nodes[NodeIndex]);
if (!Node->CheckRepresentsSoundClass())
{
UEdGraphPin* ChildPin = Node->GetChildPin();
Node->Modify();
ChildPin->BreakAllPinLinks();
if (Node->SoundClass)
{
for (int32 ChildIndex = 0; ChildIndex < Node->SoundClass->ChildClasses.Num(); ChildIndex++)
{
USoundClass* ChildClass = Node->SoundClass->ChildClasses[ChildIndex];
if (ChildClass)
{
USoundClassGraphNode* ChildNode = FindExistingNode(ChildClass);
if (!ChildNode)
{
// New Child not yet represented on graph
ConstructNodes(ChildClass, Node->NodePosX + 400, Node->NodePosY);
ChildNode = FindExistingNode(ChildClass);
}
ChildPin->MakeLinkTo(ChildNode->GetParentPin());
}
}
}
Node->PostEditChange();
}
}
NotifyGraphChanged();
}
void USoundClassGraph::RecursivelyRemoveNodes(const TSet<class UObject*> NodesToRemove)
{
Modify();
for (FGraphPanelSelectionSet::TConstIterator NodeIt(NodesToRemove); NodeIt; ++NodeIt)
{
USoundClassGraphNode* Node = Cast<USoundClassGraphNode>(*NodeIt);
if (Node && Node->CanUserDeleteNode())
{
RecursivelyRemoveNode(Node);
}
}
LinkSoundClasses();
}
int32 USoundClassGraph::ConstructNodes(class USoundClass* SoundClass, int32 NodePosX, int32 NodePosY, bool bSelectNewNode/* = true*/)
{
check(SoundClass);
TMap<USoundClass*, int32> ChildCounts;
RecursivelyGatherChildCounts(SoundClass, ChildCounts);
USoundClassGraphNode* GraphNode = CreateNode(SoundClass, NodePosX, NodePosY, bSelectNewNode);
return RecursivelyConstructChildNodes(GraphNode, ChildCounts);
}
int32 USoundClassGraph::RecursivelyGatherChildCounts(USoundClass* ParentClass, TMap<USoundClass*, int32>& OutChildCounts)
{
int32 ChildSize = 0;
for (int32 ChildIndex = 0; ChildIndex < ParentClass->ChildClasses.Num(); ChildIndex++)
{
if (ParentClass->ChildClasses[ChildIndex])
{
ChildSize += RecursivelyGatherChildCounts(ParentClass->ChildClasses[ChildIndex], OutChildCounts);
}
}
if (ChildSize == 0)
{
ChildSize = 1;
}
OutChildCounts.Add(ParentClass, ChildSize);
return ChildSize;
}
int32 USoundClassGraph::RecursivelyConstructChildNodes(USoundClassGraphNode* ParentNode, const TMap<USoundClass*, int32>& InChildCounts, bool bSelectNewNode/* = true*/)
{
const int32 HorizontalSpacing = 400;
const int32 VerticalSpacing = 100;
USoundClass* ParentClass = ParentNode->SoundClass;
int32 TotalChildSizeY = InChildCounts.FindChecked(ParentClass) * VerticalSpacing;
int32 NodeStartY = ParentNode->NodePosY - (TotalChildSizeY * 0.5f) + (VerticalSpacing * 0.5f);
int32 NodePosX = ParentNode->NodePosX + HorizontalSpacing;
for (int32 ChildIndex = 0; ChildIndex < ParentClass->ChildClasses.Num(); ChildIndex++)
{
if (ParentClass->ChildClasses[ChildIndex])
{
const int32 ChildCount = InChildCounts.FindChecked(ParentClass->ChildClasses[ChildIndex]);
int32 NodePosY = NodeStartY + (ChildCount * VerticalSpacing * 0.5f) - (VerticalSpacing * 0.5f);
USoundClassGraphNode* ChildNode = CreateNode(ParentClass->ChildClasses[ChildIndex], NodePosX, NodePosY, bSelectNewNode);
ParentNode->GetChildPin()->MakeLinkTo(ChildNode->GetParentPin());
RecursivelyConstructChildNodes(ChildNode, InChildCounts);
NodeStartY += ChildCount * VerticalSpacing;
}
}
return TotalChildSizeY;
}
void USoundClassGraph::RecursivelyRemoveNode(class USoundClassGraphNode* ParentNode)
{
UEdGraphPin* ChildPin = ParentNode->GetChildPin();
for (int32 ChildIndex = ChildPin->LinkedTo.Num() - 1; ChildIndex >= 0; ChildIndex--)
{
USoundClassGraphNode* ChildNode = CastChecked<USoundClassGraphNode>(ChildPin->LinkedTo[ChildIndex]->GetOwningNode());
RecursivelyRemoveNode(ChildNode);
}
ParentNode->Modify();
RemoveNode(ParentNode);
}
void USoundClassGraph::RemoveAllNodes()
{
TArray<UEdGraphNode*> NodesToRemove = Nodes;
for (int32 NodeIndex = 0; NodeIndex < NodesToRemove.Num(); ++NodeIndex)
{
NodesToRemove[NodeIndex]->Modify();
RemoveNode(NodesToRemove[NodeIndex]);
}
}
USoundClassGraphNode* USoundClassGraph::CreateNode(USoundClass* SoundClass, int32 NodePosX, int32 NodePosY, bool bSelectNewNode/* = true*/)
{
USoundClassGraphNode* GraphNode = FindExistingNode(SoundClass);
if (!GraphNode)
{
FGraphNodeCreator<USoundClassGraphNode> NodeCreator(*this);
GraphNode = NodeCreator.CreateNode(bSelectNewNode);
GraphNode->SoundClass = SoundClass;
GraphNode->NodePosX = NodePosX;
GraphNode->NodePosY = NodePosY;
NodeCreator.Finalize();
}
return GraphNode;
}
USoundClassGraphNode* USoundClassGraph::FindExistingNode(USoundClass* SoundClass) const
{
USoundClassGraphNode* ExistingNode = NULL;
for (int32 NodeIndex = 0; NodeIndex < Nodes.Num(); ++NodeIndex)
{
USoundClassGraphNode* Node = CastChecked<USoundClassGraphNode>(Nodes[NodeIndex]);
if (Node->SoundClass == SoundClass)
{
ExistingNode = Node;
break;
}
}
return ExistingNode;
}