예제 #1
0
void UPhysicsSerializer::Serialize( FArchive& Ar )
{
	QUICK_SCOPE_CYCLE_COUNTER(STAT_Serialize);
	Super::Serialize(Ar);
	if (Ar.UE4Ver() >= VER_UE4_BODYINSTANCE_BINARY_SERIALIZATION)
	{
		bool bCooked = Ar.IsCooking();
		Ar << bCooked;

		if (bCooked)
		{
			if (Ar.IsCooking())
			{
				TArray<FName> ActualFormatsToSave;
				ActualFormatsToSave.Add(FPlatformProperties::GetPhysicsFormat());
				BinaryFormatData.Serialize(Ar, this, &ActualFormatsToSave);
			}
			else
			{
#if WITH_PHYSX
				const uint32 Alignment = PHYSX_SERIALIZATION_ALIGNMENT;
#else
				const uint32 Alignment = DEFAULT_ALIGNMENT;
#endif
				BinaryFormatData.Serialize(Ar, this, nullptr, false, Alignment);
			}
		}
	}
}
예제 #2
0
void UBodySetup::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);


	// Load GUID (or create one for older versions)
	Ar << BodySetupGuid;

	// If we loaded a ZERO Guid, fix that
	if(Ar.IsLoading() && !BodySetupGuid.IsValid())
	{
		MarkPackageDirty();
		UE_LOG(LogPhysics, Log, TEXT("FIX GUID FOR: %s"), *GetPathName());
		BodySetupGuid = FGuid::NewGuid();
	}

	bool bCooked = Ar.IsCooking();
	Ar << bCooked;

	if (FPlatformProperties::RequiresCookedData() && !bCooked && Ar.IsLoading())
	{
		UE_LOG(LogPhysics, Fatal, TEXT("This platform requires cooked packages, and physX data was not cooked into %s."), *GetFullName());
	}

	if (bCooked)
	{
		if (Ar.IsCooking())
		{
			// Make sure to reset bHasCookedCollision data to true before calling GetCookedData for cooking
			bHasCookedCollisionData = true;
			FName Format = Ar.CookingTarget()->GetPhysicsFormat(this);
			bHasCookedCollisionData = GetCookedData(Format) != NULL; // Get the data from the DDC or build it

			TArray<FName> ActualFormatsToSave;
			ActualFormatsToSave.Add(Format);

			Ar << bHasCookedCollisionData;
			CookedFormatData.Serialize(Ar, this, &ActualFormatsToSave);
		}
		else
		{
			if (Ar.UE4Ver() >= VER_UE4_STORE_HASCOOKEDDATA_FOR_BODYSETUP)
			{
				Ar << bHasCookedCollisionData;
			}
			CookedFormatData.Serialize(Ar, this);
		}
	}

	if ( Ar.IsLoading() )
	{
		AggGeom.Serialize( Ar );
	}
}
예제 #3
0
파일: SoundCue.cpp 프로젝트: johndpope/UE4
void USoundCue::Serialize( FArchive& Ar )
{
	// Always force the duration to be updated when we are saving or cooking
	if (Ar.IsSaving() || Ar.IsCooking())
	{
		Duration = (FirstNode ? FirstNode->GetDuration() : 0.f);
	}

	Super::Serialize( Ar );

	if (!Ar.IsCooking())
	{
		Ar << SoundCueGraph;
	}
}
void ARadiantStaticMeshWebViewActor::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);

	static const int ArchiveVersion = 1;

	int Version = ArchiveVersion;

	Ar << Version;
	
	bool bCooked = Ar.IsCooking();
	Ar << bCooked;

	if (bCooked)
	{
#if WITH_EDITORONLY_DATA
		check(!Ar.IsLoading());
		if (!InteractionMesh)
		{
			ExtractInteractionMesh();
		}
#else
		check(Ar.IsLoading());
#endif
		
		Ar << InteractionMesh;
	}
}
예제 #5
0
void FRawCurveTracks::Serialize(FArchive& Ar)
{
	// @TODO: If we're about to serialize vector curve, add here
	if(Ar.UE4Ver() >= VER_UE4_SKELETON_ADD_SMARTNAMES)
	{
		for(FFloatCurve& Curve : FloatCurves)
		{
			Curve.Serialize(Ar);
		}
	}
#if WITH_EDITORONLY_DATA
	if( !Ar.IsCooking() )
	{
		if( Ar.UE4Ver() >= VER_UE4_ANIMATION_ADD_TRACKCURVES )
		{
			for( FTransformCurve& Curve : TransformCurves )
			{
				Curve.Serialize( Ar );
			}

		}
	}
#endif // WITH_EDITORONLY_DATA
	if (Ar.IsLoading())
	{
		SortFloatCurvesByUID();
	}
}
void USubstanceImageInput::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);
	Ar.UsingCustomVersion(FSubstanceCoreCustomVersion::GUID);

	//! todo: remove image date if all consumers are freezed
	if (Ar.IsSaving())
	{
		ImageRGB.StoreCompressedOnDisk(0 == CompressionRGB ? COMPRESS_ZLIB : COMPRESS_None);
		ImageA.StoreCompressedOnDisk(0 == CompressionAlpha ? COMPRESS_ZLIB : COMPRESS_None);
	}

	ImageRGB.Serialize(Ar, this);
	ImageA.Serialize(Ar, this);

	// image inputs can be used multiple times
	ImageRGB.ClearBulkDataFlags(BULKDATA_SingleUse); 
	ImageA.ClearBulkDataFlags(BULKDATA_SingleUse);

	Ar << CompressionRGB;
	Ar << CompressionAlpha;

	if (Ar.IsCooking())
	{
		SourceFilePath = FString();
		SourceFileTimestamp = FString();
	}
}
예제 #7
0
void USoundCue::Serialize(FArchive& Ar)
{
	// Always force the duration to be updated when we are saving or cooking
	if (Ar.IsSaving() || Ar.IsCooking())
	{
		Duration = (FirstNode ? FirstNode->GetDuration() : 0.f);
	}

	Super::Serialize(Ar);

	if (Ar.UE4Ver() >= VER_UE4_COOKED_ASSETS_IN_EDITOR_SUPPORT)
	{
		FStripDataFlags StripFlags(Ar);
#if WITH_EDITORONLY_DATA
		if (!StripFlags.IsEditorDataStripped())
		{
			Ar << SoundCueGraph;
		}
#endif
	}
#if WITH_EDITOR
	else
	{
		Ar << SoundCueGraph;
	}
#endif
}
예제 #8
0
void FShadowMap2D::Serialize(FArchive& Ar)
{
	FShadowMap::Serialize(Ar);
	
	if( Ar.IsCooking() && !Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::DistanceFieldShadows) )
	{
		UShadowMapTexture2D* Dummy = NULL;
		Ar << Dummy;
	}
	else
	{
		Ar << Texture;
	}

	Ar << CoordinateScale << CoordinateBias;

	for (int Channel = 0; Channel < ARRAY_COUNT(bChannelValid); Channel++)
	{
		Ar << bChannelValid[Channel];
	}

	if (Ar.UE4Ver() >= VER_UE4_STATIC_SHADOWMAP_PENUMBRA_SIZE)
	{
		Ar << InvUniformPenumbraSize;
	}
	else if (Ar.IsLoading())
	{
		const float LegacyValue = 1.0f / .05f;
		InvUniformPenumbraSize = FVector4(LegacyValue, LegacyValue, LegacyValue, LegacyValue);
	}
}
void FShaderResource::Serialize(FArchive& Ar)
{
	Ar << SpecificType;
	Ar << Target;
	Ar << Code;
	Ar << OutputHash;
	Ar << NumInstructions;
	Ar << NumTextureSamplers;
	
	if (Ar.IsLoading())
	{
		INC_DWORD_STAT_BY_FName(GetMemoryStatType((EShaderFrequency)Target.Frequency).GetName(), (int64)Code.Num());
		INC_DWORD_STAT_BY(STAT_Shaders_ShaderResourceMemory, GetSizeBytes());
		
		FShaderCache::LogShader((EShaderPlatform)Target.Platform, (EShaderFrequency)Target.Frequency, OutputHash, Code);

		// The shader resource has been serialized in, so this shader resource is now initialized.
		check(Canary != FShader::ShaderMagic_CleaningUp);
		Canary = FShader::ShaderMagic_Initialized;
	}
#if WITH_EDITORONLY_DATA
	else if(Ar.IsCooking())
	{
		FShaderCache::CookShader((EShaderPlatform)Target.Platform, (EShaderFrequency)Target.Frequency, OutputHash, Code);
	}
#endif
}
예제 #10
0
파일: SoundNode.cpp 프로젝트: johndpope/UE4
void USoundNode::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);

	if (!Ar.IsCooking())
	{
		Ar << GraphNode;
	}
}
예제 #11
0
void USoundNode::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);

	if (!Ar.IsCooking() && Ar.UE4Ver() >= VER_UE4_SOUND_CUE_GRAPH_EDITOR)
	{
		Ar << GraphNode;
	}
}
예제 #12
0
	void Serialize(FArchive& Ar, UObject* Owner, int32 Idx)
    {
		const uint8 AdjacencyDataStripFlag = 1;
		FStripDataFlags StripFlags( Ar, Ar.IsCooking() && !Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::Tessellation) ? AdjacencyDataStripFlag : 0 );

		UStaticMesh* StaticMesh = Cast<UStaticMesh>( Owner );
		bool bNeedsCPUAccess = true;

		if( !StripFlags.IsEditorDataStripped() )
        {
			RawTriangles.Serialize( Ar, Owner );
        }

		Ar << Elements;

		if( !StripFlags.IsDataStrippedForServer() )
        {
			PositionVertexBuffer.Serialize( Ar, bNeedsCPUAccess );
			VertexBuffer.Serialize( Ar, bNeedsCPUAccess );
			ColorVertexBuffer.Serialize( Ar, bNeedsCPUAccess );
			Ar << NumVertices;
			IndexBuffer.Serialize( Ar, bNeedsCPUAccess );
			if (Ar.UE4Ver() >= VER_UE4_SHADOW_ONLY_INDEX_BUFFERS)
            {		
				ShadowIndexBuffer.Serialize(Ar, bNeedsCPUAccess);
            }
			if( !StripFlags.IsEditorDataStripped() )
            {
				Ar << WireframeIndexBuffer;
            }
			if ( !StripFlags.IsClassDataStripped( AdjacencyDataStripFlag ) )
            { 					
				AdjacencyIndexBuffer.Serialize( Ar, bNeedsCPUAccess );
            }
        }

		if (Ar.IsLoading())
        {
			if (PositionVertexBuffer.GetNumVertices() != NumVertices)
            {
				PositionVertexBuffer.RemoveLegacyShadowVolumeVertices(NumVertices);
			}
			if (VertexBuffer.GetNumVertices() != NumVertices)
			{
				VertexBuffer.RemoveLegacyShadowVolumeVertices(NumVertices);
			}
			if (VertexBuffer.GetNumVertices() != NumVertices)
            {				
				ColorVertexBuffer.RemoveLegacyShadowVolumeVertices(NumVertices);
			}
        }
    }										
예제 #13
0
void UTextureCube::Serialize(FArchive& Ar)
{
	DECLARE_SCOPE_CYCLE_COUNTER(TEXT("UTextureCube::Serialize"), STAT_TextureCube_Serialize, STATGROUP_LoadTime);

	Super::Serialize(Ar);

	FStripDataFlags StripFlags(Ar);
	bool bCooked = Ar.IsCooking();
	Ar << bCooked;

	if (bCooked || Ar.IsCooking())
	{
		SerializeCookedPlatformData(Ar);
	}

#if WITH_EDITOR
	if (Ar.IsLoading() && !Ar.IsTransacting() && !bCooked)
	{
		BeginCachePlatformData();
	}
#endif // #if WITH_EDITOR
}
예제 #14
0
// Begin UObject interface. 
void UDialogueWave::Serialize( FArchive& Ar )
{
	Super::Serialize( Ar );

	Ar.ThisRequiresLocalizationGather();

	bool bCooked = Ar.IsCooking();
	Ar << bCooked;

	if (FPlatformProperties::RequiresCookedData() && !bCooked && Ar.IsLoading())
	{
		UE_LOG(LogAudio, Fatal, TEXT("This platform requires cooked packages, and audio data was not cooked into %s."), *GetFullName());
	}
}
예제 #15
0
void FStreamedAudioChunk::Serialize(FArchive& Ar, UObject* Owner, int32 ChunkIndex)
{
	bool bCooked = Ar.IsCooking();
	Ar << bCooked;

	BulkData.Serialize(Ar, Owner, ChunkIndex);
	Ar << DataSize;

#if WITH_EDITORONLY_DATA
	if (!bCooked)
	{
		Ar << DerivedDataKey;
	}
#endif // #if WITH_EDITORONLY_DATA
}
예제 #16
0
void FStreamedAudioChunk::Serialize(FArchive& Ar, UObject* Owner, int32 ChunkIndex)
{
	DECLARE_SCOPE_CYCLE_COUNTER( TEXT("FStreamedAudioChunk::Serialize"), STAT_StreamedAudioChunk_Serialize, STATGROUP_LoadTime );

	bool bCooked = Ar.IsCooking();
	Ar << bCooked;

	BulkData.Serialize(Ar, Owner, ChunkIndex);
	Ar << DataSize;

#if WITH_EDITORONLY_DATA
	if (!bCooked)
	{
		Ar << DerivedDataKey;
	}
#endif // #if WITH_EDITORONLY_DATA
}
예제 #17
0
void UUserDefinedStruct::SerializeTaggedProperties(FArchive& Ar, uint8* Data, UStruct* DefaultsStruct, uint8* Defaults, const UObject* BreakRecursionIfFullyLoad) const
{
#if WITH_EDITOR
	/*	The following code is responsible for UUserDefinedStruct's default values serialization.	*/

	auto UDDefaultsStruct = Cast<UUserDefinedStruct>(DefaultsStruct);

	const bool bDuplicate = (0 != (Ar.GetPortFlags() & PPF_Duplicate));

	/*	When saving delta, we want the difference between current data and true structure's default values. 
		When Defaults is NULL then zeroed data will be used for comparison.*/
	const bool bUseNewDefaults = !Defaults
		&& UDDefaultsStruct
		&& Ar.DoDelta()
		&& Ar.IsSaving()
		&& !bDuplicate
		&& !Ar.IsCooking();

	/*	Object serialized from delta will have missing properties filled with zeroed data, 
		we want structure's default data instead */
	const bool bLoadDefaultFirst = UDDefaultsStruct
		&& !bDuplicate
		&& Ar.IsLoading();

	const bool bPrepareDefaultStruct = bUseNewDefaults || bLoadDefaultFirst;
	FStructOnScope StructDefaultMem(bPrepareDefaultStruct ? UDDefaultsStruct : NULL);
	if (bPrepareDefaultStruct)
	{
		FStructureEditorUtils::Fill_MakeStructureDefaultValue(UDDefaultsStruct, StructDefaultMem.GetStructMemory());
	}

	if (bUseNewDefaults)
	{
		Defaults = StructDefaultMem.GetStructMemory();
	}
	if (bLoadDefaultFirst)
	{
		if (Defaults == nullptr)
		{
			Defaults = StructDefaultMem.GetStructMemory();
		}
		UDDefaultsStruct->CopyScriptStruct(Data, Defaults);
	}
#endif // WITH_EDITOR
	Super::SerializeTaggedProperties(Ar, Data, DefaultsStruct, Defaults);
}
예제 #18
0
void ULightComponent::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);

	if (Ar.UE4Ver() >= VER_UE4_STATIC_SHADOW_DEPTH_MAPS)
	{
		if (Ar.IsCooking() && !Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::HighQualityLightmaps))
		{
			// Toss lighting data only needed for high quality lightmaps
			FStaticShadowDepthMap EmptyDepthMap;
			Ar << EmptyDepthMap;
		}
		else
		{
			Ar << StaticShadowDepthMap;
		}
	}
}
예제 #19
0
void USoundWave::SerializeCookedPlatformData(FArchive& Ar)
{
	if (IsTemplate())
	{
		return;
	}

	DECLARE_SCOPE_CYCLE_COUNTER( TEXT("USoundWave::SerializeCookedPlatformData"), STAT_SoundWave_SerializeCookedPlatformData, STATGROUP_LoadTime );

#if WITH_EDITORONLY_DATA
	if (Ar.IsCooking() && Ar.IsPersistent())
	{
		check(!Ar.CookingTarget()->IsServerOnly());

		FName PlatformFormat = Ar.CookingTarget()->GetWaveFormat(this);
		FString DerivedDataKey;
		GetStreamedAudioDerivedDataKey(*this, PlatformFormat, DerivedDataKey);

		FStreamedAudioPlatformData *PlatformDataToSave = CookedPlatformData.FindRef(DerivedDataKey);

		if (PlatformDataToSave == NULL)
		{
			PlatformDataToSave = new FStreamedAudioPlatformData();
			PlatformDataToSave->Cache(*this, PlatformFormat, EStreamedAudioCacheFlags::InlineChunks | EStreamedAudioCacheFlags::Async);

			CookedPlatformData.Add(DerivedDataKey, PlatformDataToSave);
		}

		PlatformDataToSave->FinishCache();
		PlatformDataToSave->Serialize(Ar, this);
	}
	else
#endif // #if WITH_EDITORONLY_DATA
	{
		check(!FPlatformProperties::IsServerOnly());

		CleanupCachedRunningPlatformData();
		check(RunningPlatformData == NULL);

		// Don't serialize streaming data on servers, even if this platform supports streaming in theory
		RunningPlatformData = new FStreamedAudioPlatformData();
		RunningPlatformData->Serialize(Ar, this);
	}
}
예제 #20
0
void FFormatContainer::Serialize(FArchive& Ar, UObject* Owner, const TArray<FName>* FormatsToSave)
{
	if (Ar.IsLoading())
	{
		int32 NumFormats = 0;
		Ar << NumFormats;
		for (int32 Index = 0; Index < NumFormats; Index++)
		{
			FName Name;
			Ar << Name;
			FByteBulkData& Bulk = GetFormat(Name);
			Bulk.Serialize(Ar, Owner);
		}
	}
	else
	{
		check(Ar.IsCooking() && FormatsToSave); // this thing is for cooking only, and you need to provide a list of formats

		int32 NumFormats = 0;
		for (TMap<FName, FByteBulkData*>:: TIterator It(Formats); It; ++It)
		{
			if (FormatsToSave->Contains(It.Key()) && It.Value()->GetBulkDataSize() > 0)
			{
				NumFormats++;
			}
		}
		Ar << NumFormats;
		for (TMap<FName, FByteBulkData*>:: TIterator It(Formats); It; ++It)
		{
			if (FormatsToSave->Contains(It.Key()) && It.Value()->GetBulkDataSize() > 0)
			{
				NumFormats--;
				FName Name = It.Key();
				Ar << Name;
				FByteBulkData* Bulk = It.Value();
				check(Bulk);
				Bulk->Serialize(Ar, Owner);
			}
		}
		check(NumFormats == 0);
	}
}
예제 #21
0
void FShadowMap2D::Serialize(FArchive& Ar)
{
	FShadowMap::Serialize(Ar);
	
	if( Ar.IsCooking() && !Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::DistanceFieldShadows) )
	{
		UShadowMapTexture2D* Dummy = NULL;
		Ar << Dummy;
	}
	else
	{
		Ar << Texture;
	}

	Ar << CoordinateScale << CoordinateBias;

	for (int Channel = 0; Channel < ARRAY_COUNT(bChannelValid); Channel++)
	{
		Ar << bChannelValid[Channel];
	}
}
예제 #22
0
void UNavCollision::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);

	const int32 VerInitial = 1;
	const int32 VerAreaClass = 2;
	const int32 VerConvexTransforms = 3;
	const int32 VerLatest = VerConvexTransforms;

	// use magic number to determine if serialized stream has version :/
	const int32 MagicNum = 0xA237F237;
	int64 StreamStartPos = Ar.Tell();

	int32 Version = VerLatest;
	int32 MyMagicNum = MagicNum;
	Ar << MyMagicNum;

	if (MyMagicNum != MagicNum)
	{
		Version = VerInitial;
		Ar.Seek(StreamStartPos);
	}
	else
	{
		Ar << Version;
	}

	// loading a dummy GUID to have serialization not break on 
	// packages serialized before switching over UNavCollision to
	// use BodySetup's guid rather than its own one
	// motivation: not creating a new engine version
	// @NOTE could be addressed during next engine version bump
	FGuid Guid;
	Ar << Guid;
	
	bool bCooked = Ar.IsCooking();
	Ar << bCooked;

	if (FPlatformProperties::RequiresCookedData() && !bCooked && Ar.IsLoading())
	{
		UE_LOG(LogNavigation, Fatal, TEXT("This platform requires cooked packages, and NavCollision data was not cooked into %s."), *GetFullName());
	}

	if (bCooked && ShouldUseConvexCollision())
	{
		if (Ar.IsCooking())
		{
			FName Format = NAVCOLLISION_FORMAT;
			GetCookedData(Format); // Get the data from the DDC or build it

			TArray<FName> ActualFormatsToSave;
			ActualFormatsToSave.Add(Format);
			CookedFormatData.Serialize(Ar, this, &ActualFormatsToSave);
		}
		else
		{
			CookedFormatData.Serialize(Ar, this);
		}
	}

	if (Version >= VerAreaClass)
	{
		Ar << AreaClass;
	}

	if (Version < VerConvexTransforms && Ar.IsLoading() && GIsEditor)
	{
		bForceGeometryRebuild = true;
	}
}
예제 #23
0
void USoundWave::Serialize( FArchive& Ar )
{
	DECLARE_SCOPE_CYCLE_COUNTER( TEXT("USoundWave::Serialize"), STAT_SoundWave_Serialize, STATGROUP_LoadTime );

	Super::Serialize( Ar );

	bool bCooked = Ar.IsCooking();
	Ar << bCooked;

	if (FPlatformProperties::RequiresCookedData() && !bCooked && Ar.IsLoading())
	{
		UE_LOG(LogAudio, Fatal, TEXT("This platform requires cooked packages, and audio data was not cooked into %s."), *GetFullName());
	}

	Ar.UsingCustomVersion(FFrameworkObjectVersion::GUID);

	if (Ar.IsLoading() && (Ar.UE4Ver() >= VER_UE4_SOUND_COMPRESSION_TYPE_ADDED) && (Ar.CustomVer(FFrameworkObjectVersion::GUID) < FFrameworkObjectVersion::RemoveSoundWaveCompressionName))
	{
		FName DummyCompressionName;
		Ar << DummyCompressionName;
	}

	bool bSupportsStreaming = false;
	if (Ar.IsLoading() && FPlatformProperties::SupportsAudioStreaming())
	{
		bSupportsStreaming = true;
	}
	else if (Ar.IsCooking() && Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::AudioStreaming))
	{
		bSupportsStreaming = true;
	}

	if (bCooked)
	{
		// Only want to cook/load full data if we don't support streaming
		if (!IsStreaming() || !bSupportsStreaming)
		{
			if (Ar.IsCooking())
			{
#if WITH_ENGINE
				TArray<FName> ActualFormatsToSave;
				if (!Ar.CookingTarget()->IsServerOnly())
				{
					// for now we only support one format per wav
					FName Format = Ar.CookingTarget()->GetWaveFormat(this);
					GetCompressedData(Format); // Get the data from the DDC or build it

					ActualFormatsToSave.Add(Format);
				}
				CompressedFormatData.Serialize(Ar, this, &ActualFormatsToSave);
#endif
			}
			else
			{
				CompressedFormatData.Serialize(Ar, this);
			}
		}
	}
	else
	{
		// only save the raw data for non-cooked packages
		RawData.Serialize( Ar, this );
	}

	Ar << CompressedDataGuid;

	if (IsStreaming())
	{
		if (bCooked)
		{
			// only cook/load streaming data if it's supported
			if (bSupportsStreaming)
			{
				SerializeCookedPlatformData(Ar);
			}
		}

#if WITH_EDITORONLY_DATA	
		if (Ar.IsLoading() && !Ar.IsTransacting() && !bCooked && !GetOutermost()->HasAnyPackageFlags(PKG_ReloadingForCooker))
		{
			BeginCachePlatformData();
		}
#endif // #if WITH_EDITORONLY_DATA
	}
}
예제 #24
0
void USoundWave::Serialize( FArchive& Ar )
{
	Super::Serialize( Ar );

	bool bCooked = Ar.IsCooking();
	Ar << bCooked;

	if (FPlatformProperties::RequiresCookedData() && !bCooked && Ar.IsLoading())
	{
		UE_LOG(LogAudio, Fatal, TEXT("This platform requires cooked packages, and audio data was not cooked into %s."), *GetFullName());
	}

	if (Ar.IsCooking())
	{
		CompressionName = Ar.CookingTarget()->GetWaveFormat(this);
	}
	
	if (Ar.UE4Ver() >= VER_UE4_SOUND_COMPRESSION_TYPE_ADDED)
	{
		Ar << CompressionName;
	}

	if (bCooked)
	{
		// Only want to cook/load full data if we don't support streaming
		if (!IsStreaming() ||
			(Ar.IsLoading() && !FPlatformProperties::SupportsAudioStreaming()) ||
			(Ar.IsCooking() && !Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::AudioStreaming)))
		{
			if (Ar.IsCooking())
			{
#if WITH_ENGINE
				TArray<FName> ActualFormatsToSave;
				if (!Ar.CookingTarget()->IsServerOnly())
				{
					// for now we only support one format per wav
					FName Format = Ar.CookingTarget()->GetWaveFormat(this);
					GetCompressedData(Format); // Get the data from the DDC or build it

					ActualFormatsToSave.Add(Format);
				}
				CompressedFormatData.Serialize(Ar, this, &ActualFormatsToSave);
#endif
			}
			else
			{
				CompressedFormatData.Serialize(Ar, this);
			}
		}
	}
	else
	{
		// only save the raw data for non-cooked packages
		RawData.Serialize( Ar, this );
	}

	Ar << CompressedDataGuid;

	if (IsStreaming())
	{
		if (bCooked)
		{
			// only cook/load streaming data if it's supported
			if ((Ar.IsLoading() && FPlatformProperties::SupportsAudioStreaming()) ||
				(Ar.IsCooking() && Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::AudioStreaming)))
			{
				SerializeCookedPlatformData(Ar);
			}
		}

#if WITH_EDITORONLY_DATA	
		if (Ar.IsLoading() && !Ar.IsTransacting() && !bCooked && !(GetOutermost()->PackageFlags & PKG_ReloadingForCooker))
		{
			BeginCachePlatformData();
		}
#endif // #if WITH_EDITORONLY_DATA
	}
}
예제 #25
0
/**
* Serialize function used to serialize this bulk data structure.
*
* @param Ar	Archive to serialize with
* @param Owner	Object owning the bulk data
* @param Idx	Index of bulk data item being serialized
*/
void FUntypedBulkData::Serialize( FArchive& Ar, UObject* Owner, int32 Idx )
{
	check( LockStatus == LOCKSTATUS_Unlocked );

	if(Ar.IsTransacting())
	{
		// Special case for transacting bulk data arrays.

		// constructing the object during load will save it to the transaction buffer. If it tries to load the bulk data now it will try to break it.
		bool bActuallySave = Ar.IsSaving() && (!Owner || !Owner->HasAnyFlags(RF_NeedLoad));

		Ar << bActuallySave;

		if (bActuallySave)
		{
			if(Ar.IsLoading())
			{
				// Flags for bulk data.
				Ar << BulkDataFlags;
				// Number of elements in array.
				Ar << ElementCount;

				// Allocate bulk data.
				check(bShouldFreeOnEmpty);
				BulkData = FMemory::Realloc( BulkData, GetBulkDataSize() );

				// Deserialize bulk data.
				SerializeBulkData( Ar, BulkData );
			}
			else if(Ar.IsSaving())
			{
				// Flags for bulk data.
				Ar << BulkDataFlags;
				// Number of elements in array.
				Ar << ElementCount;

				// Don't attempt to load or serialize BulkData if the current size is 0.
				// This could be a newly constructed BulkData that has not yet been loaded, 
				// and allocating 0 bytes now will cause a crash when we load.
				if (GetBulkDataSize() > 0)
				{
					// Make sure bulk data is loaded.
					MakeSureBulkDataIsLoaded();

					// Serialize bulk data.
					SerializeBulkData(Ar, BulkData);
				}
			}
		}
	}
	else if( Ar.IsPersistent() && !Ar.IsObjectReferenceCollector() && !Ar.ShouldSkipBulkData() )
	{
#if TRACK_BULKDATA_USE
		FThreadSafeBulkDataToObjectMap::Get().Add( this, Owner );
#endif
		// Offset where the bulkdata flags are stored
		int64 SavedBulkDataFlagsPos	= Ar.Tell();
		Ar << BulkDataFlags;

		// Number of elements in array.
		Ar << ElementCount;
		
		// We're loading from the persistent archive.
		if( Ar.IsLoading() )
		{
			Filename = TEXT("");
			
			// @todo when Landscape (and others?) only Lock/Unlock once, we can enable this
			if (false) // FPlatformProperties::RequiresCookedData())
			{
				// Bulk data that is being serialized via seekfree loading is single use only. This allows us 
				// to free the memory as e.g. the bulk data won't be attached to an archive in the case of
				// seek free loading.
				BulkDataFlags |= BULKDATA_SingleUse;
			}

			// Size on disk, which in the case of compression is != GetBulkDataSize()
			Ar << BulkDataSizeOnDisk;
			
			Ar << BulkDataOffsetInFile;

			// fix up the file offset 
			if (Owner != NULL && Owner->GetLinker())
			{
				BulkDataOffsetInFile += Owner->GetLinker()->Summary.BulkDataStartOffset;
			}

			// determine whether the payload is stored inline or at the end of the file
			bool bPayloadInline = !(BulkDataFlags&BULKDATA_PayloadAtEndOfFile);

// 			check( (bPayloadInline && BulkDataOffsetInFile == Ar.Tell()) || 
// 				   (!bPayloadInline && BulkDataOffsetInFile > Ar.Tell()));
			
			// We're allowing defered serialization.
			if( Ar.IsAllowingLazyLoading() && Owner != NULL)
			{
				Linker = Owner->GetLinker();

#if WITH_EDITOR
				check(Linker);
				Ar.AttachBulkData( Owner, this );
				AttachedAr = &Ar;
				
#else
				check(Linker.IsValid());
				Filename = Linker->Filename;
#endif // WITH_EDITOR
				// only skip over payload, if it's stored inline
				if (bPayloadInline)
				{
					Ar.Seek( Ar.Tell() + BulkDataSizeOnDisk );
				}
			}
			// Serialize the bulk data right away.
			else
			{
				// memory for bulk data can come from preallocated GPU-accessible resource memory or default to system memory
				BulkData = GetBulkDataResourceMemory(Owner,Idx);
				if( !BulkData )
				{
					BulkData = FMemory::Realloc( BulkData, GetBulkDataSize() );
				}
				
				if (bPayloadInline)
				{
					// if the payload is stored inline, just serialize it
					SerializeBulkData( Ar, BulkData );
				}
				else
				{
					// if the payload is NOT stored inline ...
					
					// store the current file offset
					int64 CurOffset = Ar.Tell();
					// seek to the location in the file where the payload is stored
					Ar.Seek(BulkDataOffsetInFile);
					// serialize the payload
					SerializeBulkData( Ar, BulkData );
					// seek to the location we came from
					Ar.Seek(CurOffset);
				}
			}
		}
		// We're saving to the persistent archive.
		else if( Ar.IsSaving() )
		{
			// check if we save the package compressed
			UPackage* Pkg = Owner ? dynamic_cast<UPackage*>(Owner->GetOutermost()) : nullptr;
			if (Pkg && !!(Pkg->PackageFlags & PKG_StoreCompressed) )
			{
				ECompressionFlags BaseCompressionMethod = COMPRESS_Default;
				if (Ar.IsCooking())
				{
					BaseCompressionMethod = Ar.CookingTarget()->GetBaseCompressionMethod();
				}

				StoreCompressedOnDisk(BaseCompressionMethod);
			}

			// Remove single element serialization requirement before saving out bulk data flags.
			BulkDataFlags &= ~BULKDATA_ForceSingleElementSerialization;

			// Make sure bulk data is loaded.
			MakeSureBulkDataIsLoaded();
			
			// Only serialize status information if wanted.
			int64 SavedBulkDataSizeOnDiskPos	= INDEX_NONE;
			int64 SavedBulkDataOffsetInFilePos	= INDEX_NONE;
			
			// Keep track of position we are going to serialize placeholder BulkDataSizeOnDisk.
			SavedBulkDataSizeOnDiskPos = Ar.Tell();
			BulkDataSizeOnDisk = INDEX_NONE;
			// And serialize the placeholder which is going to be overwritten later.
			Ar << BulkDataSizeOnDisk;

			// Keep track of position we are going to serialize placeholder BulkDataOffsetInFile.
			SavedBulkDataOffsetInFilePos = Ar.Tell();
			BulkDataOffsetInFile = INDEX_NONE;
			// And serialize the placeholder which is going to be overwritten later.
			Ar << BulkDataOffsetInFile;

				// try to get the linkersave object
			ULinkerSave* LinkerSave = dynamic_cast<ULinkerSave*>(Ar.GetLinker());

			// determine whether we are going to store the payload inline or not.
			bool bStoreInline = !!(BulkDataFlags&BULKDATA_ForceInlinePayload) || LinkerSave == NULL;

			if (!bStoreInline)
			{
				// set the flag indicating where the payload is stored
				BulkDataFlags |= BULKDATA_PayloadAtEndOfFile;

				// with no LinkerSave we have to store the data inline
				check(LinkerSave != NULL);				
				
				// add the bulkdata storage info object to the linkersave
				int32 Index = LinkerSave->BulkDataToAppend.AddZeroed(1);
				ULinkerSave::FBulkDataStorageInfo& BulkStore = LinkerSave->BulkDataToAppend[Index];

				BulkStore.BulkDataOffsetInFilePos = SavedBulkDataOffsetInFilePos;
				BulkStore.BulkDataSizeOnDiskPos = SavedBulkDataSizeOnDiskPos;
				BulkStore.BulkData = this;
				
				// Serialize bulk data into the storage info
				BulkDataSizeOnDisk = -1;
			}
			else
			{
				// set the flag indicating where the payload is stored
				BulkDataFlags &= ~BULKDATA_PayloadAtEndOfFile;

				int64 SavedBulkDataStartPos = Ar.Tell();

				// Serialize bulk data.
				SerializeBulkData( Ar, BulkData );
				// store the payload endpos
				int64 SavedBulkDataEndPos = Ar.Tell();

				checkf(SavedBulkDataStartPos >= 0 && SavedBulkDataEndPos >= 0,
					   TEXT("Bad archive positions for bulkdata. StartPos=%d EndPos=%d"),
					   SavedBulkDataStartPos, SavedBulkDataEndPos);

				BulkDataSizeOnDisk		= SavedBulkDataEndPos - SavedBulkDataStartPos;
				BulkDataOffsetInFile	= SavedBulkDataStartPos;
			}

			// store current file offset before seeking back
			int64 CurrentFileOffset = Ar.Tell();

			// Seek back and overwrite the flags 
			Ar.Seek(SavedBulkDataFlagsPos);
			Ar << BulkDataFlags;

			// Seek back and overwrite placeholder for BulkDataSizeOnDisk
			Ar.Seek( SavedBulkDataSizeOnDiskPos );
			Ar << BulkDataSizeOnDisk;

			// Seek back and overwrite placeholder for BulkDataOffsetInFile
			Ar.Seek( SavedBulkDataOffsetInFilePos );
			Ar << BulkDataOffsetInFile;

			// Seek to the end of written data so we don't clobber any data in subsequent write 
			// operations
			Ar.Seek(CurrentFileOffset);
		}
	}
}
void UReflectionCaptureComponent::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);

	bool bCooked = false;

	if (Ar.UE4Ver() >= VER_UE4_REFLECTION_CAPTURE_COOKING)
	{
		bCooked = Ar.IsCooking();
		// Save a bool indicating whether this is cooked data
		// This is needed when loading cooked data, to know to serialize differently
		Ar << bCooked;
	}

	if (FPlatformProperties::RequiresCookedData() && !bCooked && Ar.IsLoading())
	{
		UE_LOG(LogMaterial, Fatal, TEXT("This platform requires cooked packages, and this reflection capture does not contain cooked data %s."), *GetName());
	}

	if (bCooked)
	{
		static FName FullHDR(TEXT("FullHDR"));
		static FName EncodedHDR(TEXT("EncodedHDR"));

		// Saving for cooking path
		if (Ar.IsCooking())
		{
			// Get all the reflection capture formats that the target platform wants
			TArray<FName> Formats;
			Ar.CookingTarget()->GetReflectionCaptureFormats(Formats);

			int32 NumFormats = Formats.Num();
			Ar << NumFormats;

			for (int32 FormatIndex = 0; FormatIndex < NumFormats; FormatIndex++)
			{
				FName CurrentFormat = Formats[FormatIndex];

				Ar << CurrentFormat;

				if (CurrentFormat == FullHDR)
				{
					// FullHDRDerivedData would have been set in PostLoad during cooking if it exists in the DDC
					// Can't generate it if missing, since that requires rendering the scene
					bool bValid = FullHDRDerivedData != NULL;

					Ar << bValid;

					if (bValid)
					{
						Ar << FullHDRDerivedData->CompressedCapturedData;
					}
				}
				else
				{
					check(CurrentFormat == EncodedHDR);

					TRefCountPtr<FReflectionCaptureEncodedHDRDerivedData> EncodedHDRData;
					
					// FullHDRDerivedData would have been set in PostLoad during cooking if it exists in the DDC
					// Generate temporary encoded HDR data for saving
					if (FullHDRDerivedData != NULL)
					{
						EncodedHDRData = FReflectionCaptureEncodedHDRDerivedData::GenerateEncodedHDRData(*FullHDRDerivedData, StateId, Brightness);
					}
					
					bool bValid = EncodedHDRData != NULL;

					Ar << bValid;

					if (bValid)
					{
						Ar << EncodedHDRData->CapturedData;
					}
					else if (!IsTemplate())
					{
						// Temporary warning until the cooker can do scene captures itself in the case of missing DDC
						UE_LOG(LogMaterial, Warning, TEXT("Reflection capture requires encoded HDR data but none was found in the DDC!  This reflection will be black.  Fix by loading the map in the editor once.  %s."), *GetFullName());
					}
				}
			}
		}
		else
		{
			// Loading cooked data path

			int32 NumFormats = 0;
			Ar << NumFormats;

			for (int32 FormatIndex = 0; FormatIndex < NumFormats; FormatIndex++)
			{
				FName CurrentFormat;
				Ar << CurrentFormat;

				bool bValid = false;
				Ar << bValid;

				if (bValid)
				{
					if (CurrentFormat == FullHDR)
					{
						FullHDRDerivedData = new FReflectionCaptureFullHDRDerivedData();
						Ar << FullHDRDerivedData->CompressedCapturedData;
					}
					else 
					{
						check(CurrentFormat == EncodedHDR);
						EncodedHDRDerivedData = new FReflectionCaptureEncodedHDRDerivedData();
						Ar << EncodedHDRDerivedData->CapturedData;
					}
				}
				else if (CurrentFormat == EncodedHDR)
				{
					// Temporary warning until the cooker can do scene captures itself in the case of missing DDC
					UE_LOG(LogMaterial, Error, TEXT("Reflection capture was loaded without any valid capture data and will be black.  This can happen if the DDC was not up to date during cooking.  Load the map in the editor once before cooking to fix.  %s."), *GetFullName());
				}
			}
		}
	}
}