void FCameraLensSettingsCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, class IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
{
	// Retrieve structure's child properties
	uint32 NumChildren;
	StructPropertyHandle->GetNumChildren(NumChildren);
	TMap<FName, TSharedPtr< IPropertyHandle > > PropertyHandles;
	for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex)
	{
		TSharedRef<IPropertyHandle> ChildHandle = StructPropertyHandle->GetChildHandle(ChildIndex).ToSharedRef();
		const FName PropertyName = ChildHandle->GetProperty()->GetFName();
		PropertyHandles.Add(PropertyName, ChildHandle);
	}
	
	// Retrieve special case properties
	MinFocalLengthHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FCameraLensSettings, MinFocalLength));
	MaxFocalLengthHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FCameraLensSettings, MaxFocalLength));
	MinFStopHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FCameraLensSettings, MinFStop));
	MaxFStopHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FCameraLensSettings, MaxFStop));
	MinFocusDistanceHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FCameraLensSettings, MinimumFocusDistance));

	for (auto Iter(PropertyHandles.CreateConstIterator()); Iter; ++Iter)
	{
		if (Iter.Value() == MinFocusDistanceHandle)
		{
			// skip showing these in the panel for now, as we don't really use them
			continue;
		}

		IDetailPropertyRow& SettingsRow = ChildBuilder.AddChildProperty(Iter.Value().ToSharedRef());
	}
}
Ejemplo n.º 2
0
void UUMGSequencePlayer::InitSequencePlayer( const UWidgetAnimation& InAnimation, UUserWidget& UserWidget )
{
    Animation = &InAnimation;

    UMovieScene* MovieScene = Animation->MovieScene;

    // Cache the time range of the sequence to determine when we stop
    TimeRange = MovieScene->GetTimeRange();

    RuntimeBindings = NewObject<UMovieSceneBindings>(this);
    RuntimeBindings->SetRootMovieScene( MovieScene );

    UWidgetTree* WidgetTree = UserWidget.WidgetTree;

    TMap<FGuid, TArray<UObject*> > GuidToRuntimeObjectMap;
    // Bind to Runtime Objects
    for (const FWidgetAnimationBinding& Binding : InAnimation.AnimationBindings)
    {
        UObject* FoundObject = Binding.FindRuntimeObject( *WidgetTree );

        if( FoundObject )
        {
            TArray<UObject*>& Objects = GuidToRuntimeObjectMap.FindOrAdd(Binding.AnimationGuid);
            Objects.Add(FoundObject);
        }
    }

    for( auto It = GuidToRuntimeObjectMap.CreateConstIterator(); It; ++It )
    {
        RuntimeBindings->AddBinding( It.Key(), It.Value() );
    }

}
Ejemplo n.º 3
0
void UFaceFXMatineeControl::GetTrackKeyForTime(float InTime, TArray<TPair<int32, const FFaceFXTrackKey*>>& OutResult, TArray<FFaceFXSkelMeshComponentId>* OutNoTracks) const
{
	//build a list of all keys for all skelmesh component ids
	TMap<int32, TArray<const FFaceFXTrackKey*>> SkelMeshTracks;
	TMap<int32, FFaceFXSkelMeshComponentId> SkelMeshIds;
	for(const FFaceFXTrackKey& Key : Keys)
	{
		SkelMeshTracks.FindOrAdd(Key.SkelMeshComponentId.Index).Add(&Key);
		if(OutNoTracks && !SkelMeshIds.Contains(Key.SkelMeshComponentId.Index))
		{
			SkelMeshIds.Add(Key.SkelMeshComponentId.Index, Key.SkelMeshComponentId);
		}
	}

	//then generate the pair results for each skelmesh component
	for(auto It = SkelMeshTracks.CreateConstIterator(); It; ++It)
	{
		const TArray<const FFaceFXTrackKey*>& SkelMeshKeys = It.Value();

		const int32 IndexMax = SkelMeshKeys.Num()-1;
		int32 Index = INDEX_NONE;
		for(; Index < IndexMax && SkelMeshKeys[Index+1]->Time <= InTime; ++Index);

		if(Index != INDEX_NONE)
		{
			OutResult.Add(TPairInitializer<int32, const FFaceFXTrackKey*>(Index, SkelMeshKeys[Index]));
		}
		else if(OutNoTracks)
		{
			OutNoTracks->Add(SkelMeshIds.FindChecked(It.Key()));
		}
	}
}
Ejemplo n.º 4
0
void UJavascriptEditorLibrary::GetAlphamapDataToMemory(ULandscapeInfo* LandscapeInfo, ULandscapeLayerInfoObject* LayerInfo, int32 MinX, int32 MinY, int32 MaxX, int32 MaxY)
{
	if (LayerInfo == nullptr)
	{
		return;
	}

	const int32 SizeX = (1 + MaxX - MinX);
	const int32 SizeY = (1 + MaxY - MinY);

	if (SizeX * SizeY * 1 == FArrayBufferAccessor::GetSize())
	{
		auto Buffer = (uint8*)FArrayBufferAccessor::GetData();

		FAlphamapAccessor<false, false> Accessor(LandscapeInfo, LayerInfo);

		TMap<FIntPoint, uint8> Data;
		Accessor.GetData(MinX, MinY, MaxX, MaxY, Data);

		FMemory::Memzero(Buffer, SizeX * SizeY);

		for (auto it = Data.CreateConstIterator(); it; ++it)
		{
			const auto& Point = it.Key();
			Buffer[Point.X + Point.Y * SizeX] = it.Value();
		}
	}
}
Ejemplo n.º 5
0
bool FProjectManager::LoadModulesForProject( const ELoadingPhase::Type LoadingPhase )
{
	DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Loading Game Modules"), STAT_GameModule, STATGROUP_LoadTime);

	bool bSuccess = true;

	if ( CurrentProject.IsValid() )
	{
		TMap<FName, EModuleLoadResult> ModuleLoadFailures;
		FModuleDescriptor::LoadModulesForPhase(LoadingPhase, CurrentProject->Modules, ModuleLoadFailures);

		if ( ModuleLoadFailures.Num() > 0 )
		{
			FText FailureMessage;
			for ( auto FailureIt = ModuleLoadFailures.CreateConstIterator(); FailureIt; ++FailureIt )
			{
				const EModuleLoadResult FailureReason = FailureIt.Value();

				if( FailureReason != EModuleLoadResult::Success )
				{
					const FText TextModuleName = FText::FromName(FailureIt.Key());

					if ( FailureReason == EModuleLoadResult::FileNotFound )
					{
						FailureMessage = FText::Format( LOCTEXT("PrimaryGameModuleNotFound", "The game module '{0}' could not be found. Please ensure that this module exists and that it is compiled."), TextModuleName );
					}
					else if ( FailureReason == EModuleLoadResult::FileIncompatible )
					{
						FailureMessage = FText::Format( LOCTEXT("PrimaryGameModuleIncompatible", "The game module '{0}' does not appear to be up to date. This may happen after updating the engine. Please recompile this module and try again."), TextModuleName );
					}
					else if ( FailureReason == EModuleLoadResult::FailedToInitialize )
					{
						FailureMessage = FText::Format( LOCTEXT("PrimaryGameModuleFailedToInitialize", "The game module '{0}' could not be successfully initialized after it was loaded."), TextModuleName );
					}
					else if ( FailureReason == EModuleLoadResult::CouldNotBeLoadedByOS )
					{
						FailureMessage = FText::Format( LOCTEXT("PrimaryGameModuleCouldntBeLoaded", "The game module '{0}' could not be loaded. There may be an operating system error or the module may not be properly set up."), TextModuleName );
					}
					else 
					{
						ensure(0);	// If this goes off, the error handling code should be updated for the new enum values!
						FailureMessage = FText::Format( LOCTEXT("PrimaryGameModuleGenericLoadFailure", "The game module '{0}' failed to load for an unspecified reason.  Please report this error."), TextModuleName );
					}

					// Just report the first error
					break;
				}
			}

			FMessageDialog::Open(EAppMsgType::Ok, FailureMessage);
			bSuccess = false;
		}
	}

	return bSuccess;
}
Ejemplo n.º 6
0
void FProfilerSample::FixupChildrenOrdering( const TMap<uint32,uint32>& ChildrenOrderingIndices )
{
	FIndicesArray ChildrenIndices;
	for( auto It = ChildrenOrderingIndices.CreateConstIterator(); It; ++It )
	{
		ChildrenIndices.Add( _ChildrenIndices[It.Key()] );
	}

	_ChildrenIndices = ChildrenIndices;
}
Ejemplo n.º 7
0
bool FJsonObjectConverter::JsonAttributesToUStruct(const TMap< FString, TSharedPtr<FJsonValue> >& JsonAttributes, const UStruct* StructDefinition, void* OutStruct, int64 CheckFlags, int64 SkipFlags)
{
	if (StructDefinition == FJsonObjectWrapper::StaticStruct())
	{
		// Just copy it into the object
		FJsonObjectWrapper* ProxyObject = (FJsonObjectWrapper *)OutStruct;
		ProxyObject->JsonObject = MakeShareable(new FJsonObject());
		ProxyObject->JsonObject->Values = JsonAttributes;
		return true;
	}

	// iterate over the struct properties
	for(TFieldIterator<UProperty> PropIt(StructDefinition); PropIt; ++PropIt)
	{
		UProperty* Property = *PropIt;
		FString PropertyName = Property->GetName();

		// Check to see if we should ignore this property
		if (CheckFlags != 0 && !Property->HasAnyPropertyFlags(CheckFlags))
		{
			continue;
		}
		if (Property->HasAnyPropertyFlags(SkipFlags))
		{
			continue;
		}

		// find a json value matching this property name
		TSharedPtr<FJsonValue> JsonValue;
		for (auto It = JsonAttributes.CreateConstIterator(); It; ++It)
		{
			// use case insensitive search sincd FName may change caseing strangely on us
			if (PropertyName.Equals(It.Key(), ESearchCase::IgnoreCase))
			{
				JsonValue = It.Value();
				break;
			}
		}
		if (!JsonValue.IsValid() || JsonValue->IsNull())
		{
			// we allow values to not be found since this mirrors the typical UObject mantra that all the fields are optional when deserializing
			continue;
		}

		void* Value = Property->ContainerPtrToValuePtr<uint8>(OutStruct);
		if (!JsonValueToUProperty(JsonValue, Property, Value, CheckFlags, SkipFlags))
		{
			UE_LOG(LogJson, Error, TEXT("JsonObjectToUStruct - Unable to parse %s.%s from JSON"), *StructDefinition->GetName(), *PropertyName);
			return false;
		}
	}
	
	return true;
}
bool FProvider::UpdateFileStateCache(
	const TMap<FString, TArray<FFileRevisionRef> >& InFileRevisionsMap
)
{
	for (auto It(InFileRevisionsMap.CreateConstIterator()); It; ++It)
	{
		FFileStateRef FileState = GetFileStateFromCache(It.Key());
		FileState->SetHistory(It.Value());
		FileState->SetTimeStamp(FDateTime::Now());
	}
	return InFileRevisionsMap.Num() > 0;
}
static bool UpdateCachedLocalizationStates(const TMap<FLocalizationServiceTranslationIdentifier, TSharedRef<FOneSkyLocalizationServiceState, ESPMode::ThreadSafe>, FDefaultSetAllocator, FLocalizationServiceTranslationIdentifierKeyFuncs<TSharedRef<FOneSkyLocalizationServiceState, ESPMode::ThreadSafe>>>& InResults)
{
	FOneSkyLocalizationServiceModule& OneSkyLocalizationService = FOneSkyLocalizationServiceModule::Get();
	for (auto It = InResults.CreateConstIterator(); It; ++It)
	{
		TSharedRef<FOneSkyLocalizationServiceState, ESPMode::ThreadSafe> State = OneSkyLocalizationService.GetProvider().GetStateInternal(It.Key());
		State->SetState(It.Value()->GetState());
		State->SetTranslation(It.Value()->GetTranslationString());
		State->TimeStamp = FDateTime::Now();
	}

	return InResults.Num() > 0;
}
Ejemplo n.º 10
0
float FGAEffectModifiersContainer::GatherMods(const FGameplayTagContainer& TagsIn, const TMap<FGAGameEffectHandle, TArray<FGAGameEffectModifier>>& Data)
{
	//possible optimization when needed - create separate thread.

	float ModifierVal = 0;
	float Add = 0;
	float Multiply = 1;
	float Subtract = 0;
	float Divide = 1;
	float PercentageAdd = 0;
	float PercentageSubtract = 0;
	for (auto It = Data.CreateConstIterator(); It; ++It)
	{
		for (const FGAGameEffectModifier& Test : It->Value)
		{
			if (TagsIn.MatchesAll(Test.RequiredTags, false))
			{
				switch (Test.ModType)
				{
				case EGAAttributeMod::Add:
					Add += Test.Value;
					break;
				case EGAAttributeMod::Multiply:
					Multiply += Test.Value;
					break;
				case EGAAttributeMod::Subtract:
					Subtract += Test.Value;
					break;
				case EGAAttributeMod::Divide:
					Divide += Test.Value;
					break;
				case EGAAttributeMod::PercentageAdd:
					PercentageAdd += Test.Value;
					break;
				case EGAAttributeMod::PercentageSubtract:
					PercentageSubtract += Test.Value;
					break;
				default:
					break;
				}
			}
		}
	}
	ModifierVal = ((Add - Subtract) * Multiply) / Divide;
	ModifierVal = ModifierVal + (ModifierVal * PercentageAdd);
	ModifierVal = ModifierVal - (ModifierVal * PercentageSubtract);
	SCOPE_CYCLE_COUNTER(STAT_GatherModifiers);
	return ModifierVal;
}
Ejemplo n.º 11
0
void PackageAutoSaverJson::SaveRestoreFile(const bool bRestoreEnabled, const TMap< TWeakObjectPtr<UPackage>, FString >& DirtyPackages)
{
	TSharedPtr<FJsonObject> RootObject = MakeShareable(new FJsonObject);

	RootObject->SetBoolField(TagRestoreEnabled, bRestoreEnabled);

	TArray< TSharedPtr<FJsonValue> > PackagesThatCanBeRestored;

	// Only bother populating the list of packages if the restore is enabled
	if(bRestoreEnabled)
	{
		PackagesThatCanBeRestored.Reserve(DirtyPackages.Num());

		// Build up the array of package names with auto-saves that can be restored
		for(auto It = DirtyPackages.CreateConstIterator(); It; ++It)
		{
			const TWeakObjectPtr<UPackage>& Package = It.Key();
			const FString& AutoSavePath = It.Value();

			UPackage* const PackagePtr = Package.Get();
			if(PackagePtr && !AutoSavePath.IsEmpty())
			{
				const FString& PackagePathName = PackagePtr->GetPathName();

				TSharedPtr<FJsonObject> EntryObject = MakeShareable(new FJsonObject);
				EntryObject->SetStringField(TagPackagePathName, PackagePathName);
				EntryObject->SetStringField(TagAutoSavePath, AutoSavePath);

				TSharedPtr<FJsonValue> EntryValue = MakeShareable(new FJsonValueObject(EntryObject));
				PackagesThatCanBeRestored.Add(EntryValue);
			}
		}
	}

	RootObject->SetArrayField(TagPackages, PackagesThatCanBeRestored);

	const FString Filename = GetRestoreFilename(true);
	FArchive* const FileAr = IFileManager::Get().CreateFileWriter(*Filename, FILEWRITE_EvenIfReadOnly);
	if(FileAr)
	{
		TSharedRef<FStringWriter> Writer = FStringWriterFactory::Create(FileAr);
		FJsonSerializer::Serialize(RootObject.ToSharedRef(), Writer);		
		FileAr->Close();
	}
}
void ANetworkController::ReceivedConfigureSpawner(TMap<FName, msgpack_object*> data) {

	const EDirection Direction = (EDirection)data[DIRECTION]->via.i64;
	const TArray<int64> Lanes = Unpack<TArray<int64>>(data[LANES]);
	const float MinWait = data[MIN_WAIT]->via.f64;
	const float MaxWait = data[MAX_WAIT]->via.f64;
	const TMap<FName, int64> VehicleTypes = Unpack<TMap<FName, int64>>(data[VEHICLE_TYPES]);

	for (TActorIterator<ACVehicleSpawner> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		ACVehicleSpawner* Spawner = *ObjIt;
		if (!Lanes.Contains(Spawner->Lane)) {
			continue;
		}
		if (!(Spawner->Direction == Direction)) {
			continue;
		}

		Spawner->Active = true;
		Spawner->MaxTimeWait = MaxWait;
		Spawner->MinTimeWait = MinWait;
		Spawner->VehicleTypes.Empty();
		for (auto Iter = VehicleTypes.CreateConstIterator(); Iter; ++Iter) {
			EVehicleType VehicleType = EVehicleType::VT_Car;
			if (Iter.Key() == CAR) {
				VehicleType = EVehicleType::VT_Car;
			}
			else if (Iter.Key() == SEDAN) {
				VehicleType = EVehicleType::VT_Sedan;
			}
			else if (Iter.Key() == BUS) {
				VehicleType = EVehicleType::VT_Bus;
			}
			else if (Iter.Key() == EMERGENCY) {
				VehicleType = EVehicleType::VT_Emergency;
			}
			else {
				check(false);
			}

			Spawner->VehicleTypes.Add(FVehicleTypeStruct(VehicleType, Iter.Value()));
		}

		Spawner->TurnBucket();
	}
}
	// Determine whether or not scene components in the new object set can be attached to the given scene root component
	bool CanAttachComponentsTo(USceneComponent* InRootComponent)
	{
		check(InRootComponent);

		// For each component in the set, check against the given root component and break if we fail to validate
		bool bCanAttachToRoot = true;
		for (auto NewComponentIt = NewObjectMap.CreateConstIterator(); NewComponentIt && bCanAttachToRoot; ++NewComponentIt)
		{
			// If this is a scene component, and it does not already have a parent within the set
			USceneComponent* SceneComponent = Cast<USceneComponent>(NewComponentIt->Value);
			if (SceneComponent != NULL && !ParentMap.Contains(SceneComponent->GetFName()))
			{
				// Determine if we are allowed to attach the scene component to the given root component
				bCanAttachToRoot = InRootComponent->CanAttachAsChild(SceneComponent, NAME_None)
					&& SceneComponent->Mobility >= InRootComponent->Mobility
					&& ( !InRootComponent->IsEditorOnly() || SceneComponent->IsEditorOnly() );
			}
		}

		return bCanAttachToRoot;
	}
Ejemplo n.º 14
0
void UJavascriptEditorLibrary::GetHeightmapDataToMemory(ULandscapeInfo* LandscapeInfo, int32 MinX, int32 MinY, int32 MaxX, int32 MaxY)
{
	const int32 SizeX = (1 + MaxX - MinX);
	const int32 SizeY = (1 + MaxY - MinY);

	if (SizeX * SizeY * 2 == FArrayBufferAccessor::GetSize())
	{
		auto Buffer = (uint16*)FArrayBufferAccessor::GetData();

		FHeightmapAccessor<false> Accessor(LandscapeInfo);

		TMap<FIntPoint, uint16> Data;
		Accessor.GetData(MinX, MinY, MaxX, MaxY, Data);

		FMemory::Memzero(Buffer, SizeX * SizeY * 2);

		for (auto it = Data.CreateConstIterator(); it; ++it)
		{
			const auto& Point = it.Key();
			Buffer[Point.X + Point.Y * SizeX] = it.Value();
		}
	}
}
void FCameraFilmbackSettingsCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, class IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
{
	// Retrieve structure's child properties
	uint32 NumChildren;
	StructPropertyHandle->GetNumChildren( NumChildren );	
	TMap<FName, TSharedPtr< IPropertyHandle > > PropertyHandles;	
	for( uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex )
	{
		TSharedRef<IPropertyHandle> ChildHandle = StructPropertyHandle->GetChildHandle( ChildIndex ).ToSharedRef();
		const FName PropertyName = ChildHandle->GetProperty()->GetFName();

		PropertyHandles.Add(PropertyName, ChildHandle);
	}
	
	// Retrieve special case properties
	SensorWidthHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FCameraFilmbackSettings, SensorWidth));
	SensorHeightHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FCameraFilmbackSettings, SensorHeight));

	for( auto Iter(PropertyHandles.CreateConstIterator()); Iter; ++Iter  )
	{
		IDetailPropertyRow& SettingsRow = ChildBuilder.AddChildProperty(Iter.Value().ToSharedRef());
	}	
}
Ejemplo n.º 16
0
void SDetailsViewBase::QueryCustomDetailLayout(FDetailLayoutBuilderImpl& CustomDetailLayout)
{
	FPropertyEditorModule& ParentPlugin = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");

	// Get the registered classes that customize details
	FCustomDetailLayoutNameMap& GlobalCustomLayoutNameMap = ParentPlugin.ClassNameToDetailLayoutNameMap;

	UStruct* BaseStruct = GetBaseStruct();

	// All the current customization instances need to be deleted when it is safe
	CustomizationClassInstancesPendingDelete = CustomizationClassInstances;

	CustomizationClassInstances.Empty();

	//Ask for generic details not specific to an object being viewed 
	if (GenericLayoutDelegate.IsBound())
	{
		// Create a new instance of the custom detail layout for the current class
		TSharedRef<IDetailCustomization> CustomizationInstance = GenericLayoutDelegate.Execute();

		// Ask for details immediately
		CustomizationInstance->CustomizeDetails(CustomDetailLayout);

		// Save the instance from destruction until we refresh
		CustomizationClassInstances.Add(CustomizationInstance);
	}


	// Sort them by query order.  @todo not good enough
	struct FCompareFDetailLayoutCallback
	{
		FORCEINLINE bool operator()(const FDetailLayoutCallback& A, const FDetailLayoutCallback& B) const
		{
			return A.Order < B.Order;
		}
	};

	TMap< TWeakObjectPtr<UStruct>, FDetailLayoutCallback*> FinalCallbackMap;

	for (auto ClassIt = ClassesWithProperties.CreateConstIterator(); ClassIt; ++ClassIt)
	{
		// Check the instanced map first
		FDetailLayoutCallback* Callback = InstancedClassToDetailLayoutMap.Find(*ClassIt);

		if (!Callback)
		{
			// callback wasn't found in the per instance map, try the global instances instead
			Callback = GlobalCustomLayoutNameMap.Find((*ClassIt)->GetFName());
		}

		if (Callback)
		{
			FinalCallbackMap.Add(*ClassIt, Callback);
		}
	}


	FinalCallbackMap.ValueSort(FCompareFDetailLayoutCallback());

	TSet<UStruct*> QueriedClasses;

	if (FinalCallbackMap.Num() > 0)
	{
		// Ask each class that we have properties for to customize its layout
		for (auto LayoutIt(FinalCallbackMap.CreateConstIterator()); LayoutIt; ++LayoutIt)
		{
			const TWeakObjectPtr<UStruct> WeakClass = LayoutIt.Key();

			if (WeakClass.IsValid())
			{
				UStruct* Class = WeakClass.Get();

				FClassInstanceToPropertyMap& InstancedPropertyMap = ClassToPropertyMap.FindChecked(Class->GetFName());
				for (FClassInstanceToPropertyMap::TIterator InstanceIt(InstancedPropertyMap); InstanceIt; ++InstanceIt)
				{
					FName Key = InstanceIt.Key();
					CustomDetailLayout.SetCurrentCustomizationClass(CastChecked<UClass>(Class), Key);

					const FOnGetDetailCustomizationInstance& DetailDelegate = LayoutIt.Value()->DetailLayoutDelegate;

					if (DetailDelegate.IsBound())
					{
						QueriedClasses.Add(Class);

						// Create a new instance of the custom detail layout for the current class
						TSharedRef<IDetailCustomization> CustomizationInstance = DetailDelegate.Execute();

						// Ask for details immediately
						CustomizationInstance->CustomizeDetails(CustomDetailLayout);

						// Save the instance from destruction until we refresh
						CustomizationClassInstances.Add(CustomizationInstance);
					}
				}
			}
		}
	}

	// Ensure that the base class and its parents are always queried
	TSet<UStruct*> ParentClassesToQuery;
	if (BaseStruct && !QueriedClasses.Contains(BaseStruct))
	{
		ParentClassesToQuery.Add(BaseStruct);
		ClassesWithProperties.Add(BaseStruct);
	}

	// Find base classes of queried classes that were not queried and add them to the query list
	// this supports cases where a parent class has no properties but still wants to add customization
	for (auto QueriedClassIt = ClassesWithProperties.CreateConstIterator(); QueriedClassIt; ++QueriedClassIt)
	{
		UStruct* ParentStruct = (*QueriedClassIt)->GetSuperStruct();

		while (ParentStruct && ParentStruct->IsA(UClass::StaticClass()) && !QueriedClasses.Contains(ParentStruct) && !ClassesWithProperties.Contains(ParentStruct))
		{
			ParentClassesToQuery.Add(ParentStruct);
			ParentStruct = ParentStruct->GetSuperStruct();

		}
	}

	// Query extra base classes
	for (auto ParentIt = ParentClassesToQuery.CreateConstIterator(); ParentIt; ++ParentIt)
	{
		if (Cast<UClass>(*ParentIt))
		{
			QueryLayoutForClass(CustomDetailLayout, *ParentIt);
		}
	}
}
int32 UGatherTextCommandlet::Main( const FString& Params )
{
	const TCHAR* Parms = *Params;
	TArray<FString> Tokens;
	TArray<FString> Switches;
	TMap<FString, FString> ParamVals;
	UCommandlet::ParseCommandLine(*Params, Tokens, Switches, ParamVals);
	
	// find the file corresponding to this object's loc file, loading it if necessary
	FString GatherTextConfigPath;
	const FString* ParamVal = ParamVals.Find(FString(TEXT("Config")));
	if (ParamVal)
	{
		GatherTextConfigPath = *ParamVal;
	}	
	else
	{
		UE_LOG(LogGatherTextCommandlet, Error, TEXT("-Config not specified.\n%s"), *UsageText);
		return -1;
	}

	if(FPaths::IsRelative(GatherTextConfigPath))
	{
		FString ProjectBasePath;
		if (!FPaths::GameDir().IsEmpty())
		{
			ProjectBasePath = FPaths::GameDir();
		}
		else
		{
			ProjectBasePath = FPaths::EngineDir();
		}
		GatherTextConfigPath = FPaths::Combine( *ProjectBasePath, *GatherTextConfigPath );
	}

	GConfig->LoadFile(*GatherTextConfigPath);

	FConfigFile* ConfigFile = GConfig->FindConfigFile(*GatherTextConfigPath);

	if( NULL == ConfigFile )
	{
		UE_LOG(LogGatherTextCommandlet, Error, TEXT("Loading Config File \"%s\" failed."), *GatherTextConfigPath);
		return -1; 
	}

	const bool bEnableSourceControl = Switches.Contains(TEXT("EnableSCC"));
	const bool bDisableSubmit = Switches.Contains(TEXT("DisableSCCSubmit"));

	UE_LOG(LogGatherTextCommandlet, Log,TEXT("Beginning GatherText Commandlet."));

	TSharedPtr< FGatherTextSCC > CommandletSourceControlInfo = nullptr;

	if( bEnableSourceControl )
	{
		CommandletSourceControlInfo = MakeShareable( new FGatherTextSCC() );

		FText SCCErrorStr;
		if( !CommandletSourceControlInfo->IsReady( SCCErrorStr ) )
		{
			UE_LOG( LogGatherTextCommandlet, Error, TEXT("Source Control error: %s"), *SCCErrorStr.ToString() );
			return -1;
		}
	}

	// Basic helper that can be used only to gather a new manifest for writing
	TSharedRef<FLocTextHelper> CommandletGatherManifestHelper = MakeShareable(new FLocTextHelper(MakeShareable(new FLocFileSCCNotifies(CommandletSourceControlInfo))));
	CommandletGatherManifestHelper->LoadManifest(ELocTextHelperLoadFlags::Create);

	int32 NumSteps = (ConfigFile->Find("CommonSettings") != NULL) ? ConfigFile->Num() - 1 :  ConfigFile->Num();

	//Execute each step defined in the config file.
	for( int32 i=0; i<NumSteps ; ++i )
	{
		FString SectionName = FString::Printf(TEXT("GatherTextStep%d"),i);
		FConfigSection* CurrCommandletSection = ConfigFile->Find(SectionName);
		if( NULL == CurrCommandletSection )
		{
			UE_LOG(LogGatherTextCommandlet, Error, TEXT("Could not find %s"),*SectionName);
			continue;
		}

		FString CommandletClassName = GConfig->GetStr( *SectionName, TEXT("CommandletClass"), GatherTextConfigPath ) + TEXT("Commandlet");

		UClass* CommandletClass = FindObject<UClass>(ANY_PACKAGE,*CommandletClassName,false);
		if (!CommandletClass)
		{
			UE_LOG(LogGatherTextCommandlet, Error,TEXT("The commandlet name %s in section %s is invalid."), *CommandletClassName, *SectionName);
			continue;
		}

		UGatherTextCommandletBase* Commandlet = NewObject<UGatherTextCommandletBase>(GetTransientPackage(), CommandletClass);
		check(Commandlet);
		Commandlet->AddToRoot();
		Commandlet->Initialize( CommandletGatherManifestHelper, CommandletSourceControlInfo );

		// Execute the commandlet.
		double CommandletExecutionStartTime = FPlatformTime::Seconds();

		UE_LOG(LogGatherTextCommandlet, Log,TEXT("Executing %s: %s"), *SectionName, *CommandletClassName);
		
		
		FString GeneratedCmdLine = FString::Printf(TEXT("-Config=\"%s\" -Section=%s"), *GatherTextConfigPath , *SectionName);

		// Add all the command params with the exception of config
		for(auto ParamIter = ParamVals.CreateConstIterator(); ParamIter; ++ParamIter)
		{
			const FString& Key = ParamIter.Key();
			const FString& Val = ParamIter.Value();
			if(Key != TEXT("config"))
			{
				GeneratedCmdLine += FString::Printf(TEXT(" -%s=%s"), *Key , *Val);
			}	
		}

		// Add all the command switches
		for(auto SwitchIter = Switches.CreateConstIterator(); SwitchIter; ++SwitchIter)
		{
			const FString& Switch = *SwitchIter;
			GeneratedCmdLine += FString::Printf(TEXT(" -%s"), *Switch);
		}

		if( 0 != Commandlet->Main( GeneratedCmdLine ) )
		{
			UE_LOG(LogGatherTextCommandlet, Error,TEXT("%s-%s reported an error."),*SectionName, *CommandletClassName);
			if( CommandletSourceControlInfo.IsValid() )
			{
				FText SCCErrorStr;
				if( !CommandletSourceControlInfo->CleanUp( SCCErrorStr ) )
				{
					UE_LOG(LogGatherTextCommandlet, Error, TEXT("%s"), *SCCErrorStr.ToString());
				}
			}
			return -1;
		}

		UE_LOG(LogGatherTextCommandlet, Log,TEXT("Completed %s: %s"), *SectionName, *CommandletClassName);
	}

	if( CommandletSourceControlInfo.IsValid() && !bDisableSubmit )
	{
		FText SCCErrorStr;
		if( CommandletSourceControlInfo->CheckinFiles( GetChangelistDescription(GatherTextConfigPath), SCCErrorStr ) )
		{
			UE_LOG(LogGatherTextCommandlet, Log,TEXT("Submitted Localization files."));
		}
		else
		{
			UE_LOG(LogGatherTextCommandlet, Error, TEXT("%s"), *SCCErrorStr.ToString());
			if( !CommandletSourceControlInfo->CleanUp( SCCErrorStr ) )
			{
				UE_LOG(LogGatherTextCommandlet, Error, TEXT("%s"), *SCCErrorStr.ToString());
			}
			return -1;
		}
	}

	return 0;
}
Ejemplo n.º 18
0
void FBuildPatchAppManifest::EnumerateProducibleChunks( const FString& InstallDirectory, const TArray< FGuid >& ChunksRequired, TArray< FGuid >& ChunksAvailable ) const
{
	// A struct that will store byte ranges
	struct FChunkRange
	{
		// The inclusive min byte
		uint32 Min;
		// The inclusive max byte
		uint32 Max;
	};
	// A struct that will sort an FChunkRange array by Min
	struct FCompareFChunkRangeByMin
	{
		FORCEINLINE bool operator()( const FChunkRange& A, const FChunkRange& B ) const
		{
			return A.Min < B.Min;
		}
	};
	// The first thing we need is an inventory of FFileChunkParts that we can get which refer to our required chunks
	TMap< FGuid, TArray< FFileChunkPart > > ChunkPartInventory;
	EnumerateChunkPartInventory( ChunksRequired, ChunkPartInventory );

	// For each chunk that we found a part for, check that the union of chunk parts we have for it, contains all bytes of the chunk
	for( auto ChunkPartInventoryIt = ChunkPartInventory.CreateConstIterator(); ChunkPartInventoryIt; ++ChunkPartInventoryIt )
	{
		// Create an array of FChunkRanges that describes the chunk data that we have available
		const FGuid& ChunkGuid = ChunkPartInventoryIt.Key();
		const TArray< FFileChunkPart >& ChunkParts = ChunkPartInventoryIt.Value();
		if( ChunksAvailable.Contains( ChunkGuid ) )
		{
			continue;
		}
		TArray< FChunkRange > ChunkRanges;
		for( auto ChunkPartIt = ChunkParts.CreateConstIterator(); ChunkPartIt; ++ChunkPartIt )
		{
			const FFileChunkPart& FileChunkPart = *ChunkPartIt;
			const int64 SourceFilesize = IFileManager::Get().FileSize( *(InstallDirectory / FileChunkPart.Filename) );
			const int64 LastRequiredByte = FileChunkPart.FileOffset + FileChunkPart.ChunkPart.Size;
			if( SourceFilesize == GetFileSize( FileChunkPart.Filename ) && SourceFilesize >= LastRequiredByte )
			{
				const uint32 Min = FileChunkPart.ChunkPart.Offset;
				const uint32 Max = Min + FileChunkPart.ChunkPart.Size - 1;
				// We will store our ranges using inclusive values
				FChunkRange NextRange;
				NextRange.Min = Min;
				NextRange.Max = Max;
				ChunkRanges.Add( NextRange );
			}
		}
		ChunkRanges.Sort( FCompareFChunkRangeByMin() );
		// Now we have a sorted array of ChunkPart ranges, we walk this array to find a gap in available data
		// which would mean we cannot generate this chunk
		uint32 ByteCount = 0;
		for( auto ChunkRangeIt = ChunkRanges.CreateConstIterator(); ChunkRangeIt; ++ChunkRangeIt )
		{
			const FChunkRange& ChunkRange = *ChunkRangeIt;
			if( ChunkRange.Min <= ByteCount && ChunkRange.Max >= ByteCount )
			{
				ByteCount = ChunkRange.Max;
			}
			else
			{
				break;
			}
		}
		// If we can make the chunk, add it to the list
		const bool bCanMakeChunk = ByteCount == ( FBuildPatchData::ChunkDataSize - 1 );
		if( bCanMakeChunk )
		{
			ChunksAvailable.AddUnique( ChunkGuid );
		}
	}
}
void FAssetTypeActions_SoundCue::ExecuteConsolidateAttenuation(TArray<TWeakObjectPtr<USoundCue>> Objects)
{
	TMap<FAttenuationSettings*,TArray<USoundCue*>> UnmatchedAttenuations;

	for (auto ObjIt = Objects.CreateConstIterator(); ObjIt; ++ObjIt)
	{
		USoundCue* SoundCue = (*ObjIt).Get();
		bool bFound = false;
		if ( SoundCue && SoundCue->bOverrideAttenuation )
		{
			for (auto UnmatchedIt = UnmatchedAttenuations.CreateIterator(); UnmatchedIt; ++UnmatchedIt)
			{
				// Found attenuation settings to consolidate together
				if (SoundCue->AttenuationOverrides == *UnmatchedIt.Key())
				{
					UnmatchedIt.Value().Add(SoundCue);
					bFound = true;
					break;
				}
			}
			if (!bFound)
			{
				UnmatchedAttenuations.FindOrAdd(&SoundCue->AttenuationOverrides).Add(SoundCue);
			}
		}
	}

	if (UnmatchedAttenuations.Num() > 0)
	{
		FString DefaultSuffix;
		TArray<UObject*> ObjectsToSync;

		FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
		USoundAttenuationFactory* Factory = ConstructObject<USoundAttenuationFactory>(USoundAttenuationFactory::StaticClass());

		for (auto UnmatchedIt = UnmatchedAttenuations.CreateConstIterator(); UnmatchedIt; ++UnmatchedIt)
		{
			if (UnmatchedIt.Value().Num() > 1)
			{
				FString Name;
				FString PackageName;
				CreateUniqueAssetName("/Game/Sounds/SoundAttenuations/SharedAttenuation", DefaultSuffix, PackageName, Name);

				USoundAttenuation* SoundAttenuation = Cast<USoundAttenuation>(AssetToolsModule.Get().CreateAsset(Name, FPackageName::GetLongPackagePath(PackageName), USoundAttenuation::StaticClass(), Factory));
				if (SoundAttenuation)
				{
					SoundAttenuation->Attenuation = *UnmatchedIt.Key();

					for (int32 SoundCueIndex = 0; SoundCueIndex < UnmatchedIt.Value().Num(); ++SoundCueIndex)
					{
						USoundCue* SoundCue = UnmatchedIt.Value()[SoundCueIndex];
						SoundCue->bOverrideAttenuation = false;
						SoundCue->AttenuationSettings = SoundAttenuation;
						SoundCue->MarkPackageDirty();
					}
				}
			}
		}

		if ( ObjectsToSync.Num() > 0 )
		{
			FAssetTools::Get().SyncBrowserToAssets(ObjectsToSync);
		}
	}
}
Ejemplo n.º 20
0
void FPhysxSharedData::DumpSharedMemoryUsage(FOutputDevice* Ar)
{
	struct FSharedResourceEntry
	{
		uint64 MemorySize;
		uint64 Count;
	};

	struct FSortBySize
	{
		FORCEINLINE bool operator()( const FSharedResourceEntry& A, const FSharedResourceEntry& B ) const 
		{ 
			// Sort descending
			return B.MemorySize < A.MemorySize;
		}
	};

	TMap<FString, FSharedResourceEntry> AllocationsByType;

	uint64 OverallSize = 0;
	int32 OverallCount = 0;

	TMap<FString, TArray<PxBase*> > ObjectsByType;

	for (int32 i=0; i < (int32)SharedObjects->getNbObjects(); ++i)
	{
		PxBase& Obj = SharedObjects->getObject(i);
		FString TypeName = ANSI_TO_TCHAR(Obj.getConcreteTypeName());

		TArray<PxBase*>* ObjectsArray = ObjectsByType.Find(TypeName);
		if (ObjectsArray == NULL)
		{
			ObjectsByType.Add(TypeName, TArray<PxBase*>());
			ObjectsArray = ObjectsByType.Find(TypeName);
		}

		check(ObjectsArray);
		ObjectsArray->Add(&Obj);
	}

	TArray<FString> TypeNames;
	ObjectsByType.GetKeys(TypeNames);

	for (int32 TypeIdx=0; TypeIdx < TypeNames.Num(); ++TypeIdx)
	{
		const FString& TypeName = TypeNames[TypeIdx];
		
		TArray<PxBase*>* ObjectsArray = ObjectsByType.Find(TypeName);
		check(ObjectsArray);

		PxSerializationRegistry* Sr = PxSerialization::createSerializationRegistry(*GPhysXSDK);
		PxCollection* Collection = PxCreateCollection();
		
		for (int32 i=0; i < ObjectsArray->Num(); ++i)
		{
			Collection->add(*((*ObjectsArray)[i]));;
		}

		PxSerialization::complete(*Collection, *Sr);	// chase all other stuff (shared shaps, materials, etc) needed to serialize this collection

		FPhysXCountMemoryStream Out;
		PxSerialization::serializeCollectionToBinary(Out, *Collection, *Sr);

		Collection->release();
		Sr->release();

		OverallSize += Out.UsedMemory;
		OverallCount += ObjectsArray->Num();

		FSharedResourceEntry NewEntry;
		NewEntry.Count = ObjectsArray->Num();
		NewEntry.MemorySize = Out.UsedMemory;

		AllocationsByType.Add(TypeName, NewEntry);
	}

	Ar->Logf(TEXT(""));
	Ar->Logf(TEXT("Shared Resources:"));
	Ar->Logf(TEXT(""));

	AllocationsByType.ValueSort(FSortBySize());
	
	Ar->Logf(TEXT("%-10d %s (%d)"), OverallSize, TEXT("Overall"), OverallCount );
	
	for( auto It=AllocationsByType.CreateConstIterator(); It; ++It )
	{
		Ar->Logf(TEXT("%-10d %s (%d)"), It.Value().MemorySize, *It.Key(), It.Value().Count );
	}
}
void UPhyaCollisionHandler::HandlePhysicsCollisions_AssumesLocked(TArray<FCollisionNotifyInfo>& PendingCollisionNotifies)
{
	if(GetWorld()->HasBegunPlay())
	{
		TMap< FPhyaBodyInstancePair, TSharedPtr<FPhyaPairInfo> > ExpiredPairHash = PairHash;

		for(int32 InfoIdx=0; InfoIdx<PendingCollisionNotifies.Num(); InfoIdx++)
		{
			const FCollisionNotifyInfo& Info = PendingCollisionNotifies[InfoIdx];
			FPhyaBodyInstancePair Pair(Info.Info0.GetBodyInstance(), Info.Info1.GetBodyInstance());
			// Find pair in hash
			TSharedPtr<FPhyaPairInfo> PairInfo = PairHash.FindRef(Pair);

			// Existing pair
			if(PairInfo.IsValid())
			{
				UE_LOG(LogTemp, Log, TEXT("EXISTING"));

				ExpiredPairHash.Remove(Pair); // Not expired
			}
			// New pair
			else
			{
				UE_LOG(LogTemp, Log, TEXT("NEW"));

				PairInfo = MakeShareable( new FPhyaPairInfo );
				PairHash.Add(Pair, PairInfo);

				paImpact* Impact = paImpact::newImpact();
				if(Impact != NULL)
				{
					Impact->setBody1(Bodies[0]);

					paImpactDynamicData ImpactData;
					ImpactData.relTangentSpeedAtImpact = 0; // No skid.
					ImpactData.impactImpulse = 1.0;

					Impact->setDynamicData(&ImpactData);
				}
			}

		}

		// Expire pairs from PairHash still in ExpiredPairHash
		for( auto It = ExpiredPairHash.CreateConstIterator(); It; ++It )
		{
			UE_LOG(LogTemp, Log, TEXT("EXPIRE"));
			FPhyaBodyInstancePair Pair = It.Key();
			PairHash.Remove(Pair);
		}

		/*
		float WorldTime = GetWorld()->GetTimeSeconds();
		float TimeSinceLastTestImpact = WorldTime - LastTestImpactTime;
		if(TimeSinceLastTestImpact > 1.f)
		{
			TestImpact();
			LastTestImpactTime = WorldTime;
		}
		*/
	}
}
bool FPluginManager::LoadModulesForEnabledPlugins( const ELoadingPhase::Type LoadingPhase )
{
	// Figure out which plugins are enabled
	if(!ConfigureEnabledPlugins())
	{
		return false;
	}

	FScopedSlowTask SlowTask(AllPlugins.Num());

	// Load plugins!
	for( const TSharedRef< FPlugin > Plugin : AllPlugins )
	{
		SlowTask.EnterProgressFrame(1);

		if ( Plugin->bEnabled )
		{
			TMap<FName, EModuleLoadResult> ModuleLoadFailures;
			FModuleDescriptor::LoadModulesForPhase(LoadingPhase, Plugin->Descriptor.Modules, ModuleLoadFailures);

			FText FailureMessage;
			for( auto FailureIt( ModuleLoadFailures.CreateConstIterator() ); FailureIt; ++FailureIt )
			{
				const auto ModuleNameThatFailedToLoad = FailureIt.Key();
				const auto FailureReason = FailureIt.Value();

				if( FailureReason != EModuleLoadResult::Success )
				{
					const FText PluginNameText = FText::FromString(Plugin->Name);
					const FText TextModuleName = FText::FromName(FailureIt.Key());

					if ( FailureReason == EModuleLoadResult::FileNotFound )
					{
						FailureMessage = FText::Format( LOCTEXT("PluginModuleNotFound", "Plugin '{0}' failed to load because module '{1}' could not be found.  Please ensure the plugin is properly installed, otherwise consider disabling the plugin for this project."), PluginNameText, TextModuleName );
					}
					else if ( FailureReason == EModuleLoadResult::FileIncompatible )
					{
						FailureMessage = FText::Format( LOCTEXT("PluginModuleIncompatible", "Plugin '{0}' failed to load because module '{1}' does not appear to be compatible with the current version of the engine.  The plugin may need to be recompiled."), PluginNameText, TextModuleName );
					}
					else if ( FailureReason == EModuleLoadResult::CouldNotBeLoadedByOS )
					{
						FailureMessage = FText::Format( LOCTEXT("PluginModuleCouldntBeLoaded", "Plugin '{0}' failed to load because module '{1}' could not be loaded.  There may be an operating system error or the module may not be properly set up."), PluginNameText, TextModuleName );
					}
					else if ( FailureReason == EModuleLoadResult::FailedToInitialize )
					{
						FailureMessage = FText::Format( LOCTEXT("PluginModuleFailedToInitialize", "Plugin '{0}' failed to load because module '{1}' could be initialized successfully after it was loaded."), PluginNameText, TextModuleName );
					}
					else 
					{
						ensure(0);	// If this goes off, the error handling code should be updated for the new enum values!
						FailureMessage = FText::Format( LOCTEXT("PluginGenericLoadFailure", "Plugin '{0}' failed to load because module '{1}' could not be loaded for an unspecified reason.  This plugin's functionality will not be available.  Please report this error."), PluginNameText, TextModuleName );
					}

					// Don't need to display more than one module load error per plugin that failed to load
					break;
				}
			}

			if( !FailureMessage.IsEmpty() )
			{
				FMessageDialog::Open(EAppMsgType::Ok, FailureMessage);
				return false;
			}
		}
	}
	return true;
}
void FAttenuationSettingsCustomization::CustomizeChildren( TSharedRef<IPropertyHandle> StructPropertyHandle, class IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils )
{
	uint32 NumChildren;
	StructPropertyHandle->GetNumChildren( NumChildren );

	TMap<FName, TSharedPtr< IPropertyHandle > > PropertyHandles;

	for( uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex )
	{
		TSharedRef<IPropertyHandle> ChildHandle = StructPropertyHandle->GetChildHandle( ChildIndex ).ToSharedRef();
		const FName PropertyName = ChildHandle->GetProperty()->GetFName();

		PropertyHandles.Add(PropertyName, ChildHandle);
	}

	// We'll set up reset to default ourselves
	const bool bDisplayResetToDefault = false;
	const FString DisplayNameOverride = TEXT("");

	AttenuationShapeHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, AttenuationShape));
	DistanceAlgorithmHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, DistanceAlgorithm));
	SpatializationAlgorithmHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, SpatializationAlgorithm));

	TSharedRef<IPropertyHandle> AttenuationExtentsHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, AttenuationShapeExtents)).ToSharedRef();

	uint32 NumExtentChildren;
	AttenuationExtentsHandle->GetNumChildren( NumExtentChildren );

	TSharedPtr< IPropertyHandle > ExtentXHandle;
	TSharedPtr< IPropertyHandle > ExtentYHandle;
	TSharedPtr< IPropertyHandle > ExtentZHandle;

	for( uint32 ExtentChildIndex = 0; ExtentChildIndex < NumExtentChildren; ++ExtentChildIndex )
	{
		TSharedRef<IPropertyHandle> ChildHandle = AttenuationExtentsHandle->GetChildHandle( ExtentChildIndex ).ToSharedRef();
		const FName PropertyName = ChildHandle->GetProperty()->GetFName();

		if (PropertyName == GET_MEMBER_NAME_CHECKED(FVector, X))
		{
			ExtentXHandle = ChildHandle;
		}
		else if (PropertyName == GET_MEMBER_NAME_CHECKED(FVector, Y))
		{
			ExtentYHandle = ChildHandle;
		}
		else
		{
			check(PropertyName == GET_MEMBER_NAME_CHECKED(FVector, Z));
			ExtentZHandle = ChildHandle;
		}
	}

	ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, bAttenuate)).ToSharedRef());
	ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, bSpatialize)).ToSharedRef());
	ChildBuilder.AddChildProperty(DistanceAlgorithmHandle.ToSharedRef() );

	// Check to see if a spatialization plugin is enabled
	if (IsAudioPluginEnabled(EAudioPlugin::SPATIALIZATION))
	{
		ChildBuilder.AddChildProperty(SpatializationAlgorithmHandle.ToSharedRef());
	}

	IDetailPropertyRow& CustomCurveRow = ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, CustomAttenuationCurve)).ToSharedRef());
	CustomCurveRow.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsCustomCurveSelected));

	IDetailPropertyRow& dbAttenuationRow = ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, dBAttenuationAtMax)).ToSharedRef());
	dbAttenuationRow.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsNaturalSoundSelected));

	IDetailPropertyRow& AttenuationShapeRow = ChildBuilder.AddChildProperty( AttenuationShapeHandle.ToSharedRef() );
	
	ChildBuilder.AddChildProperty(AttenuationExtentsHandle)
		.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsBoxSelected))
		.DisplayName(NSLOCTEXT("AttenuationSettings", "BoxExtentsLabel", "Extents"))
		.ToolTip(NSLOCTEXT("AttenuationSettings", "BoxExtents", "The dimensions of the of the box."));

	ChildBuilder.AddChildContent(NSLOCTEXT("AttenuationSettings", "RadiusLabel", "Radius"))
		.NameContent()
		[
			SNew(STextBlock)
				.Text(NSLOCTEXT("AttenuationSettings", "RadiusLabel", "Radius"))
				.ToolTipText(NSLOCTEXT("AttenuationSettings", "RadiusToolTip", "The distance from the location of the sound at which falloff begins."))
				.Font(StructCustomizationUtils.GetRegularFont())
		]
		.ValueContent()
		[
			ExtentXHandle->CreatePropertyValueWidget()
		]
		.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsSphereSelected));

	ChildBuilder.AddChildContent(NSLOCTEXT("AttenuationSettings", "CapsuleHalfHeightLabel", "Capsule Half Height"))
			.NameContent()
			[
				SNew(STextBlock)
				.Text(NSLOCTEXT("AttenuationSettings", "CapsuleHalfHeightLabel", "Capsule Half Height"))
				.ToolTipText(NSLOCTEXT("AttenuationSettings", "CapsuleHalfHeightToolTip", "The attenuation capsule's half height."))
				.Font(StructCustomizationUtils.GetRegularFont())
			]
		.ValueContent()
			[
				ExtentXHandle->CreatePropertyValueWidget()
			]
		.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsCapsuleSelected));

	ChildBuilder.AddChildContent(NSLOCTEXT("AttenuationSettings", "CapsuleRadiusLabel", "Capsule Radius"))
		.NameContent()
		[
			SNew(STextBlock)
			.Text(NSLOCTEXT("AttenuationSettings", "CapsuleRadiusLabel", "Capsule Radius"))
			.ToolTipText(NSLOCTEXT("AttenuationSettings", "CapsuleRadiusToolTip", "The attenuation capsule's radius."))
			.Font(StructCustomizationUtils.GetRegularFont())
		]
	.ValueContent()
		[
			ExtentYHandle->CreatePropertyValueWidget()
		]
	.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsCapsuleSelected));

	ChildBuilder.AddChildContent(NSLOCTEXT("AttenuationSettings", "ConeRadiusLabel", "Cone Radius"))
		.NameContent()
		[
			SNew(STextBlock)
			.Text(NSLOCTEXT("AttenuationSettings", "ConeRadiusLabel", "Cone Radius"))
			.ToolTipText(NSLOCTEXT("AttenuationSettings", "ConeRadiusToolTip", "The attenuation cone's radius."))
			.Font(StructCustomizationUtils.GetRegularFont())
		]
	.ValueContent()
		[
			ExtentXHandle->CreatePropertyValueWidget()
		]
	.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsConeSelected));

	ChildBuilder.AddChildContent(NSLOCTEXT("AttenuationSettings", "ConeAngleLabel", "Cone Angle"))
		.NameContent()
		[
			SNew(STextBlock)
			.Text(NSLOCTEXT("AttenuationSettings", "ConeAngleLabel", "Cone Angle"))
			.ToolTipText(NSLOCTEXT("AttenuationSettings", "ConeAngleToolTip", "The angle of the inner edge of the attenuation cone's falloff. Inside this angle sounds will be at full volume."))
			.Font(StructCustomizationUtils.GetRegularFont())
		]
	.ValueContent()
		[
			ExtentYHandle->CreatePropertyValueWidget()
		]
	.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsConeSelected));

	ChildBuilder.AddChildContent(NSLOCTEXT("AttenuationSettings", "ConeFalloffAngleLabel", "Cone Falloff Angle"))
		.NameContent()
		[
			SNew(STextBlock)
			.Text(NSLOCTEXT("AttenuationSettings", "ConeFalloffAngleLabel", "Cone Falloff Angle"))
			.ToolTipText(NSLOCTEXT("AttenuationSettings", "ConeFalloffAngleToolTip", "The angle of the outer edge of the attenuation cone's falloff. Outside this angle sounds will be inaudible."))
			.Font(StructCustomizationUtils.GetRegularFont())
		]
	.ValueContent()
		[
			ExtentZHandle->CreatePropertyValueWidget()
		]
	.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsConeSelected));

	IDetailPropertyRow& ConeOffsetRow = ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, ConeOffset)).ToSharedRef());
	ConeOffsetRow.Visibility(TAttribute<EVisibility>(this, &FAttenuationSettingsCustomization::IsConeSelected));

	ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, FalloffDistance)).ToSharedRef());
	ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, OmniRadius)).ToSharedRef());
	ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, bAttenuateWithLPF)).ToSharedRef());
	ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, LPFRadiusMin)).ToSharedRef());
	ChildBuilder.AddChildProperty(PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FAttenuationSettings, LPFRadiusMax)).ToSharedRef());

	if (PropertyHandles.Num() != 14)
	{
		FString PropertyList;
		for (auto It(PropertyHandles.CreateConstIterator()); It; ++It)
		{
			PropertyList += It.Key().ToString() + TEXT(", ");
		}
		ensureMsgf(false, TEXT("Unexpected property handle(s) customizing FAttenuationSettings: %s"), *PropertyList);
	}
}
Ejemplo n.º 24
0
void BuildResourceTableMapping(
	const TMap<FString,FResourceTableEntry>& ResourceTableMap,
	const TMap<FString,uint32>& ResourceTableLayoutHashes,
	TBitArray<>& UsedUniformBufferSlots,
	FShaderParameterMap& ParameterMap,
	FShaderResourceTable& OutSRT)
{
	check(OutSRT.ResourceTableBits == 0);
	check(OutSRT.ResourceTableLayoutHashes.Num() == 0);

	// Build resource table mapping
	int32 MaxBoundResourceTable = -1;
	TArray<uint32> ResourceTableSRVs;
	TArray<uint32> ResourceTableSamplerStates;
	TArray<uint32> ResourceTableUAVs;

	for( auto MapIt = ResourceTableMap.CreateConstIterator(); MapIt; ++MapIt )
	{
		const FString& Name	= MapIt->Key;
		const FResourceTableEntry& Entry = MapIt->Value;

		uint16 BufferIndex, BaseIndex, Size;
		if (ParameterMap.FindParameterAllocation( *Name, BufferIndex, BaseIndex, Size ) )
		{
			ParameterMap.RemoveParameterAllocation(*Name);

			uint16 UniformBufferIndex = INDEX_NONE, UBBaseIndex, UBSize;
			if (ParameterMap.FindParameterAllocation(*Entry.UniformBufferName, UniformBufferIndex, UBBaseIndex, UBSize) == false)
			{
				UniformBufferIndex = UsedUniformBufferSlots.FindAndSetFirstZeroBit();
				ParameterMap.AddParameterAllocation(*Entry.UniformBufferName,UniformBufferIndex,0,0);
			}

			OutSRT.ResourceTableBits |= (1 << UniformBufferIndex);
			MaxBoundResourceTable = FMath::Max<int32>(MaxBoundResourceTable, (int32)UniformBufferIndex);

			while (OutSRT.ResourceTableLayoutHashes.Num() <= MaxBoundResourceTable)
			{
				OutSRT.ResourceTableLayoutHashes.Add(0);
			}
			OutSRT.ResourceTableLayoutHashes[UniformBufferIndex] = ResourceTableLayoutHashes.FindChecked(Entry.UniformBufferName);

			auto ResourceMap = FRHIResourceTableEntry::Create(UniformBufferIndex, Entry.ResourceIndex, BaseIndex);
			switch( Entry.Type )
			{
			case UBMT_TEXTURE:
				OutSRT.TextureMap.Add(ResourceMap);
				break;
			case UBMT_SAMPLER:
				OutSRT.SamplerMap.Add(ResourceMap);
				break;
			case UBMT_SRV:
				OutSRT.ShaderResourceViewMap.Add(ResourceMap);
				break;
			case UBMT_UAV:
				OutSRT.UnorderedAccessViewMap.Add(ResourceMap);
				break;
			default:
				check(0);
			}
		}
	}

	OutSRT.MaxBoundResourceTable = MaxBoundResourceTable;
}