2019-12-26 15:32:37 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-10-04 13:11:45 -04:00
# include "DatasmithFacadeScene.h"
// Datasmith facade.
2020-09-24 00:43:27 -04:00
# include "DatasmithFacadeActor.h"
2019-10-04 13:11:45 -04:00
# include "DatasmithFacadeElement.h"
# include "DatasmithFacadeMaterial.h"
2020-09-24 00:43:27 -04:00
# include "DatasmithFacadeMesh.h"
# include "DatasmithFacadeMetaData.h"
# include "DatasmithFacadeTexture.h"
2021-06-10 13:13:24 -04:00
# include "DatasmithFacadeVariant.h"
2021-09-09 04:06:30 -04:00
# include "DatasmithFacadeAnimation.h"
2019-10-04 13:11:45 -04:00
// Datasmith SDK.
# include "DatasmithExporterManager.h"
2021-02-03 14:57:28 -04:00
# include "DatasmithExportOptions.h"
2019-10-04 13:11:45 -04:00
# include "DatasmithSceneExporter.h"
# include "Misc/Paths.h"
FDatasmithFacadeScene : : FDatasmithFacadeScene (
const TCHAR * InApplicationHostName ,
const TCHAR * InApplicationVendorName ,
const TCHAR * InApplicationProductName ,
const TCHAR * InApplicationProductVersion
) :
2020-09-24 00:43:27 -04:00
SceneRef ( FDatasmithSceneFactory : : CreateScene ( TEXT ( " " ) ) ) ,
2021-02-03 14:57:28 -04:00
SceneExporterRef ( MakeShared < FDatasmithSceneExporter > ( ) )
2019-10-04 13:11:45 -04:00
{
2021-02-03 14:57:28 -04:00
// Set the name of the host application used to build the scene.
SceneRef - > SetHost ( InApplicationHostName ) ;
// Set the vendor name of the application used to build the scene.
SceneRef - > SetVendor ( InApplicationVendorName ) ;
// Set the product name of the application used to build the scene.
SceneRef - > SetProductName ( InApplicationProductName ) ;
// Set the product version of the application used to build the scene.
SceneRef - > SetProductVersion ( InApplicationProductVersion ) ;
2019-10-04 13:11:45 -04:00
}
2020-09-24 00:43:27 -04:00
void FDatasmithFacadeScene : : AddActor (
FDatasmithFacadeActor * InActorPtr
2019-10-04 13:11:45 -04:00
)
{
2021-02-03 14:57:28 -04:00
if ( InActorPtr )
{
SceneRef - > AddActor ( InActorPtr - > GetDatasmithActorElement ( ) ) ;
}
2019-10-04 13:11:45 -04:00
}
2020-09-24 00:43:27 -04:00
int32 FDatasmithFacadeScene : : GetActorsCount ( ) const
2019-10-04 13:11:45 -04:00
{
2020-09-24 00:43:27 -04:00
return SceneRef - > GetActorsCount ( ) ;
}
2019-10-04 13:11:45 -04:00
2020-09-24 00:43:27 -04:00
FDatasmithFacadeActor * FDatasmithFacadeScene : : GetNewActor (
int32 ActorIndex
)
{
if ( TSharedPtr < IDatasmithActorElement > ActorElement = SceneRef - > GetActor ( ActorIndex ) )
{
return FDatasmithFacadeActor : : GetNewFacadeActorFromSharedPtr ( ActorElement ) ;
}
return nullptr ;
}
void FDatasmithFacadeScene : : RemoveActor (
FDatasmithFacadeActor * InActorPtr ,
EActorRemovalRule RemovalRule
)
{
SceneRef - > RemoveActor ( InActorPtr - > GetDatasmithActorElement ( ) , static_cast < EDatasmithActorRemovalRule > ( RemovalRule ) ) ;
}
void FDatasmithFacadeScene : : AddMaterial (
FDatasmithFacadeBaseMaterial * InMaterialPtr
)
{
2021-02-03 14:57:28 -04:00
if ( InMaterialPtr )
{
SceneRef - > AddMaterial ( InMaterialPtr - > GetDatasmithBaseMaterial ( ) ) ;
}
2020-09-24 00:43:27 -04:00
}
int32 FDatasmithFacadeScene : : GetMaterialsCount ( ) const
{
return SceneRef - > GetMaterialsCount ( ) ;
}
FDatasmithFacadeBaseMaterial * FDatasmithFacadeScene : : GetNewMaterial (
int32 MaterialIndex
)
{
if ( TSharedPtr < IDatasmithBaseMaterialElement > ActorElement = SceneRef - > GetMaterial ( MaterialIndex ) )
{
return FDatasmithFacadeBaseMaterial : : GetNewFacadeBaseMaterialFromSharedPtr ( ActorElement ) ;
}
return nullptr ;
}
void FDatasmithFacadeScene : : RemoveMaterial (
FDatasmithFacadeBaseMaterial * InMaterialPtr
)
{
if ( InMaterialPtr )
{
SceneRef - > RemoveMaterial ( InMaterialPtr - > GetDatasmithBaseMaterial ( ) ) ;
2019-10-04 13:11:45 -04:00
}
}
2021-02-03 14:57:28 -04:00
FDatasmithFacadeMeshElement * FDatasmithFacadeScene : : ExportDatasmithMesh (
FDatasmithFacadeMesh * Mesh ,
FDatasmithFacadeMesh * CollisionMesh /*= nullptr*/
2020-09-24 00:43:27 -04:00
)
2019-10-04 13:11:45 -04:00
{
2021-02-03 14:57:28 -04:00
TSharedPtr < IDatasmithMeshElement > ExportedMeshElement ;
FString AssetOutputPath = SceneExporterRef - > GetAssetsOutputPath ( ) ;
if ( Mesh & & ! AssetOutputPath . IsEmpty ( ) )
{
FDatasmithMesh & MeshRef = Mesh - > GetDatasmithMesh ( ) ;
FDatasmithMesh * CollitionMeshPtr = CollisionMesh ? & CollisionMesh - > GetDatasmithMesh ( ) : nullptr ;
ExportedMeshElement = FDatasmithMeshExporter ( ) . ExportToUObject ( * AssetOutputPath , Mesh - > GetName ( ) , MeshRef , CollitionMeshPtr , FDatasmithExportOptions : : LightmapUV ) ;
}
return ExportedMeshElement . IsValid ( ) ? new FDatasmithFacadeMeshElement ( ExportedMeshElement . ToSharedRef ( ) ) : nullptr ;
}
bool FDatasmithFacadeScene : : ExportDatasmithMesh (
FDatasmithFacadeMeshElement * MeshElement ,
FDatasmithFacadeMesh * Mesh ,
FDatasmithFacadeMesh * CollisionMesh /*= nullptr*/
)
{
TSharedPtr < IDatasmithMeshElement > ExportedMeshElement ;
FString AssetOutputPath = SceneExporterRef - > GetAssetsOutputPath ( ) ;
if ( MeshElement & & Mesh & & ! AssetOutputPath . IsEmpty ( ) )
{
TSharedPtr < IDatasmithMeshElement > MeshElementSharedPtr = MeshElement - > GetDatasmithMeshElement ( ) ;
FDatasmithMesh & MeshRef = Mesh - > GetDatasmithMesh ( ) ;
FDatasmithMesh * CollitionMeshPtr = CollisionMesh ? & CollisionMesh - > GetDatasmithMesh ( ) : nullptr ;
return FDatasmithMeshExporter ( ) . ExportToUObject ( MeshElementSharedPtr , * AssetOutputPath , MeshRef , CollitionMeshPtr , FDatasmithExportOptions : : LightmapUV ) ;
}
return false ;
}
void FDatasmithFacadeScene : : AddMesh (
FDatasmithFacadeMeshElement * InMeshPtr
)
{
if ( InMeshPtr )
{
SceneRef - > AddMesh ( InMeshPtr - > GetDatasmithMeshElement ( ) ) ;
}
}
FDatasmithFacadeMeshElement * FDatasmithFacadeScene : : GetNewMesh (
int32 MeshIndex
)
{
if ( const TSharedPtr < IDatasmithMeshElement > DSMesh = SceneRef - > GetMesh ( MeshIndex ) )
{
return new FDatasmithFacadeMeshElement ( DSMesh . ToSharedRef ( ) ) ;
}
return nullptr ;
}
void FDatasmithFacadeScene : : RemoveMesh (
FDatasmithFacadeMeshElement * InMeshElementPtr
)
{
if ( InMeshElementPtr )
{
SceneRef - > RemoveMesh ( InMeshElementPtr - > GetDatasmithMeshElement ( ) ) ;
}
2020-09-24 00:43:27 -04:00
}
void FDatasmithFacadeScene : : AddTexture (
FDatasmithFacadeTexture * InTexturePtr
)
{
2021-02-03 14:57:28 -04:00
if ( InTexturePtr )
{
// Make sure ElementHash is valid
TSharedRef < IDatasmithTextureElement > TextureElement = InTexturePtr - > GetDatasmithTextureElement ( ) ;
FMD5Hash FileHash = FMD5Hash : : HashFile ( TextureElement - > GetFile ( ) ) ;
TextureElement - > SetFileHash ( FileHash ) ;
TextureElement - > CalculateElementHash ( true ) ;
SceneRef - > AddTexture ( TextureElement ) ;
}
2020-09-24 00:43:27 -04:00
}
int32 FDatasmithFacadeScene : : GetTexturesCount ( ) const
{
return SceneRef - > GetTexturesCount ( ) ;
}
FDatasmithFacadeTexture * FDatasmithFacadeScene : : GetNewTexture (
int32 TextureIndex
)
{
if ( TSharedPtr < IDatasmithTextureElement > TextureElement = SceneRef - > GetTexture ( TextureIndex ) )
2019-10-04 13:11:45 -04:00
{
2020-09-24 00:43:27 -04:00
return new FDatasmithFacadeTexture ( TextureElement . ToSharedRef ( ) ) ;
2019-10-04 13:11:45 -04:00
}
2020-09-24 00:43:27 -04:00
return nullptr ;
}
void FDatasmithFacadeScene : : RemoveTexture (
FDatasmithFacadeTexture * InTexturePtr
)
{
SceneRef - > RemoveTexture ( InTexturePtr - > GetDatasmithTextureElement ( ) ) ;
}
2021-09-09 04:06:30 -04:00
void FDatasmithFacadeScene : : AddLevelSequence (
FDatasmithFacadeLevelSequence * InLevelSequence
)
{
if ( InLevelSequence )
{
SceneRef - > AddLevelSequence ( InLevelSequence - > GetDatasmithLevelSequence ( ) ) ;
}
}
int32 FDatasmithFacadeScene : : GetLevelSequencesCount ( ) const
{
return SceneRef - > GetLevelSequencesCount ( ) ;
}
FDatasmithFacadeLevelSequence * FDatasmithFacadeScene : : GetNewLevelSequence (
int32 LevelSequenceIndex
)
{
if ( TSharedPtr < IDatasmithLevelSequenceElement > LevelSequenceElement = SceneRef - > GetLevelSequence ( LevelSequenceIndex ) )
{
return new FDatasmithFacadeLevelSequence ( LevelSequenceElement . ToSharedRef ( ) ) ;
}
return nullptr ;
}
void FDatasmithFacadeScene : : RemoveLevelSequence (
FDatasmithFacadeLevelSequence * InLevelSequence
)
{
SceneRef - > RemoveLevelSequence ( InLevelSequence - > GetDatasmithLevelSequence ( ) ) ;
}
2021-06-10 13:13:24 -04:00
void FDatasmithFacadeScene : : AddLevelVariantSets (
FDatasmithFacadeLevelVariantSets * InLevelVariantSetsPtr
)
{
if ( InLevelVariantSetsPtr )
{
SceneRef - > AddLevelVariantSets ( InLevelVariantSetsPtr - > GetDatasmithLevelVariantSets ( ) ) ;
}
}
int32 FDatasmithFacadeScene : : GetLevelVariantSetsCount ( ) const
{
return SceneRef - > GetLevelVariantSetsCount ( ) ;
}
FDatasmithFacadeLevelVariantSets * FDatasmithFacadeScene : : GetNewLevelVariantSets (
int32 LevelVariantSetsIndex
)
{
if ( TSharedPtr < IDatasmithLevelVariantSetsElement > LevelVariantSetsElement = SceneRef - > GetLevelVariantSets ( LevelVariantSetsIndex ) )
{
return new FDatasmithFacadeLevelVariantSets ( LevelVariantSetsElement . ToSharedRef ( ) ) ;
}
return nullptr ;
}
void FDatasmithFacadeScene : : RemoveLevelVariantSets (
FDatasmithFacadeLevelVariantSets * InLevelVariantSetsPtr
)
{
SceneRef - > RemoveLevelVariantSets ( InLevelVariantSetsPtr - > GetDatasmithLevelVariantSets ( ) ) ;
}
2020-09-24 00:43:27 -04:00
void FDatasmithFacadeScene : : AddMetaData (
FDatasmithFacadeMetaData * InMetaData
)
{
2021-02-03 14:57:28 -04:00
if ( InMetaData )
{
SceneRef - > AddMetaData ( InMetaData - > GetDatasmithMetaDataElement ( ) ) ;
}
2020-09-24 00:43:27 -04:00
}
int32 FDatasmithFacadeScene : : GetMetaDataCount ( ) const
{
return SceneRef - > GetMetaDataCount ( ) ;
}
FDatasmithFacadeMetaData * FDatasmithFacadeScene : : GetNewMetaData (
int32 MetaDataIndex
)
{
if ( TSharedPtr < IDatasmithMetaDataElement > MetaDataElement = SceneRef - > GetMetaData ( MetaDataIndex ) )
{
return new FDatasmithFacadeMetaData ( MetaDataElement . ToSharedRef ( ) ) ;
}
return nullptr ;
}
2021-02-03 14:57:28 -04:00
FDatasmithFacadeMetaData * FDatasmithFacadeScene : : GetNewMetaData (
FDatasmithFacadeElement * Element
)
{
if ( Element )
{
if ( TSharedPtr < IDatasmithMetaDataElement > MetaDataElement = SceneRef - > GetMetaData ( Element - > GetDatasmithElement ( ) ) )
{
return new FDatasmithFacadeMetaData ( MetaDataElement . ToSharedRef ( ) ) ;
}
}
return nullptr ;
}
2020-09-24 00:43:27 -04:00
void FDatasmithFacadeScene : : RemoveMetaData (
FDatasmithFacadeMetaData * InMetaDataPtr
)
{
SceneRef - > RemoveMetaData ( InMetaDataPtr - > GetDatasmithMetaDataElement ( ) ) ;
2019-10-04 13:11:45 -04:00
}
2020-09-24 00:43:27 -04:00
//This function is a temporary workaround to make sure Materials and texture are not deleted from the scene.
//There won't be a need to reset the scene once all the Facade elements will stop generating DatasmithElement on the fly (and duplicating the data) during BuildElement()
void ResetBuiltFacadeElement ( TSharedRef < IDatasmithScene > & SceneRef )
{
TArray < TSharedPtr < IDatasmithMeshElement > > MeshesArray ;
TArray < TSharedPtr < IDatasmithBaseMaterialElement > > MaterialArray ;
TArray < TSharedPtr < IDatasmithTextureElement > > TextureArray ;
TArray < TSharedPtr < IDatasmithMetaDataElement > > MetaDataArray ;
TArray < TSharedPtr < IDatasmithActorElement > > ActorArray ;
TArray < TSharedPtr < IDatasmithLevelSequenceElement > > LevelSequences ;
TArray < TSharedPtr < IDatasmithLevelVariantSetsElement > > LevelVariantSets ;
const int32 MeshCount = SceneRef - > GetMeshesCount ( ) ;
const int32 MaterialCount = SceneRef - > GetMaterialsCount ( ) ;
const int32 TextureCount = SceneRef - > GetTexturesCount ( ) ;
const int32 MetaDataCount = SceneRef - > GetMetaDataCount ( ) ;
const int32 ActorCount = SceneRef - > GetActorsCount ( ) ;
const int32 LevelSequencesCount = SceneRef - > GetLevelSequencesCount ( ) ;
const int32 LevelVariantSetsCount = SceneRef - > GetLevelVariantSetsCount ( ) ;
MeshesArray . Reserve ( MeshCount ) ;
MaterialArray . Reserve ( MaterialCount ) ;
TextureArray . Reserve ( TextureCount ) ;
MetaDataArray . Reserve ( MetaDataCount ) ;
ActorArray . Reserve ( ActorCount ) ;
LevelSequences . Reserve ( LevelSequencesCount ) ;
LevelVariantSets . Reserve ( LevelVariantSetsCount ) ;
//Backup Meshes, Materials and Textures before reseting the scene in order to restore them.
for ( int32 MeshIndex = 0 ; MeshIndex < MeshCount ; + + MeshIndex )
{
MeshesArray . Add ( SceneRef - > GetMesh ( MeshIndex ) ) ;
}
for ( int32 MaterialIndex = 0 ; MaterialIndex < MaterialCount ; + + MaterialIndex )
{
MaterialArray . Add ( SceneRef - > GetMaterial ( MaterialIndex ) ) ;
}
for ( int32 TextureIndex = 0 ; TextureIndex < TextureCount ; + + TextureIndex )
{
TextureArray . Add ( SceneRef - > GetTexture ( TextureIndex ) ) ;
}
for ( int32 MetaDataIndex = 0 ; MetaDataIndex < MetaDataCount ; + + MetaDataIndex )
{
MetaDataArray . Add ( SceneRef - > GetMetaData ( MetaDataIndex ) ) ;
}
for ( int32 ActorIndex = 0 ; ActorIndex < ActorCount ; + + ActorIndex )
{
ActorArray . Add ( SceneRef - > GetActor ( ActorIndex ) ) ;
}
for ( int32 LevelSequenceIndex = 0 ; LevelSequenceIndex < LevelSequencesCount ; + + LevelSequenceIndex )
{
LevelSequences . Add ( SceneRef - > GetLevelSequence ( LevelSequenceIndex ) ) ;
}
for ( int32 LevelVariantSetIndex = 0 ; LevelVariantSetIndex < LevelVariantSetsCount ; + + LevelVariantSetIndex )
{
LevelVariantSets . Add ( SceneRef - > GetLevelVariantSets ( LevelVariantSetIndex ) ) ;
}
SceneRef - > Reset ( ) ;
for ( TSharedPtr < IDatasmithMeshElement > & CurrentMesh : MeshesArray )
{
SceneRef - > AddMesh ( CurrentMesh ) ;
}
for ( TSharedPtr < IDatasmithBaseMaterialElement > & CurrentMaterial : MaterialArray )
{
SceneRef - > AddMaterial ( CurrentMaterial ) ;
}
for ( TSharedPtr < IDatasmithTextureElement > & CurrentTexture : TextureArray )
{
SceneRef - > AddTexture ( CurrentTexture ) ;
}
for ( TSharedPtr < IDatasmithMetaDataElement > & CurrentMetaData : MetaDataArray )
{
SceneRef - > AddMetaData ( CurrentMetaData ) ;
}
for ( TSharedPtr < IDatasmithLevelSequenceElement > & CurrentLevelSequence : LevelSequences )
{
SceneRef - > AddLevelSequence ( CurrentLevelSequence . ToSharedRef ( ) ) ;
}
for ( TSharedPtr < IDatasmithLevelVariantSetsElement > & CurrentLevelVariantSet : LevelVariantSets )
{
SceneRef - > AddLevelVariantSets ( CurrentLevelVariantSet ) ;
}
for ( TSharedPtr < IDatasmithActorElement > & CurrentActor : ActorArray )
{
SceneRef - > AddActor ( CurrentActor ) ;
}
}
2021-02-03 14:57:28 -04:00
void FDatasmithFacadeScene : : CleanUp ( )
2019-10-04 13:11:45 -04:00
{
2021-02-03 14:57:28 -04:00
FDatasmithSceneUtils : : CleanUpScene ( SceneRef , true ) ;
2019-10-04 13:11:45 -04:00
}
2020-02-25 10:49:26 -05:00
void FDatasmithFacadeScene : : PreExport ( )
2019-10-04 13:11:45 -04:00
{
// Initialize the Datasmith exporter module.
FDatasmithExporterManager : : Initialize ( ) ;
// Start measuring the time taken to export the scene.
SceneExporterRef - > PreExport ( ) ;
2020-02-25 10:49:26 -05:00
}
2021-02-03 14:57:28 -04:00
void FDatasmithFacadeScene : : SetName ( const TCHAR * InName )
{
SceneExporterRef - > SetName ( InName ) ;
SceneRef - > SetName ( SceneExporterRef - > GetName ( ) ) ;
}
const TCHAR * FDatasmithFacadeScene : : GetName ( ) const
{
return SceneExporterRef - > GetName ( ) ;
}
void FDatasmithFacadeScene : : SetOutputPath ( const TCHAR * InOutputPath )
{
SceneExporterRef - > SetOutputPath ( InOutputPath ) ;
SceneRef - > SetResourcePath ( SceneExporterRef - > GetOutputPath ( ) ) ;
}
const TCHAR * FDatasmithFacadeScene : : GetOutputPath ( ) const
{
return SceneExporterRef - > GetOutputPath ( ) ;
}
const TCHAR * FDatasmithFacadeScene : : GetAssetsOutputPath ( ) const
{
return SceneExporterRef - > GetAssetsOutputPath ( ) ;
}
2020-10-29 13:38:15 -04:00
void FDatasmithFacadeScene : : Shutdown ( )
{
FDatasmithExporterManager : : Shutdown ( ) ;
}
2021-02-03 14:57:28 -04:00
bool FDatasmithFacadeScene : : ExportScene (
2021-06-10 13:13:24 -04:00
const TCHAR * InOutputPath ,
bool bCleanupUnusedElements
2020-02-25 10:49:26 -05:00
)
{
FString OutputPath = InOutputPath ;
2019-10-04 13:11:45 -04:00
// Set the name of the scene to export and let Datasmith sanitize it when required.
FString SceneName = FPaths : : GetBaseFilename ( OutputPath ) ;
2021-02-03 14:57:28 -04:00
SetName ( * SceneName ) ;
2019-10-04 13:11:45 -04:00
// Set the output folder where this scene will be exported.
FString SceneFolder = FPaths : : GetPath ( OutputPath ) ;
2021-02-03 14:57:28 -04:00
SetOutputPath ( * SceneFolder ) ;
2019-10-04 13:11:45 -04:00
2021-06-10 13:13:24 -04:00
return ExportScene ( bCleanupUnusedElements ) ;
2021-02-03 14:57:28 -04:00
}
2019-10-04 13:11:45 -04:00
2021-06-10 13:13:24 -04:00
bool FDatasmithFacadeScene : : ExportScene ( bool bCleanupUnusedElements )
2021-02-03 14:57:28 -04:00
{
if ( FCString : : Strlen ( SceneExporterRef - > GetName ( ) ) = = 0
| | FCString : : Strlen ( SceneExporterRef - > GetOutputPath ( ) ) = = 0 )
{
return false ;
}
2020-09-24 00:43:27 -04:00
2019-10-04 13:11:45 -04:00
// Export the Datasmith scene instance into its file.
2021-06-10 13:13:24 -04:00
SceneExporterRef - > Export ( SceneRef , bCleanupUnusedElements ) ;
2021-02-03 14:57:28 -04:00
return true ;
2019-10-04 13:11:45 -04:00
}
TSharedRef < IDatasmithScene > FDatasmithFacadeScene : : GetScene ( ) const
{
return SceneRef ;
}
2020-09-24 00:43:27 -04:00
void FDatasmithFacadeScene : : SetLabel ( const TCHAR * InSceneLabel )
{
SceneRef - > SetLabel ( InSceneLabel ) ;
}
const TCHAR * FDatasmithFacadeScene : : GetLabel ( ) const
{
return SceneRef - > GetLabel ( ) ;
}