UDestructibleMesh* ImportDestructibleMeshFromApexDestructibleAsset(UObject* InParent, NxDestructibleAsset& ApexDestructibleAsset, FName Name, EObjectFlags Flags, FSkeletalMeshImportData* OutData, EDestructibleImportOptions::Type Options)
{
	// The APEX Destructible Asset contains an APEX Render Mesh Asset, get a pointer to this
	const physx::NxRenderMeshAsset* ApexRenderMesh = ApexDestructibleAsset.getRenderMeshAsset();
	if (ApexRenderMesh == NULL)
	{
		return NULL;
	}

	// Number of submeshes (aka "elements" in Unreal)
	const physx::PxU32 SubmeshCount = ApexRenderMesh->getSubmeshCount();
	if (SubmeshCount == 0)
	{
		return NULL;
	}

	// Make sure rendering is done - so we are not changing data being used by collision drawing.
	FlushRenderingCommands();

	UDestructibleMesh* DestructibleMesh = FindObject<UDestructibleMesh>(InParent, *Name.ToString());
	if (DestructibleMesh == NULL)
	{
		// Create the new UDestructibleMesh object if the one with the same name does not exist
		DestructibleMesh = NewObject<UDestructibleMesh>(InParent, Name, Flags);
	}
	
	if (!(Options & EDestructibleImportOptions::PreserveSettings))
	{
		// Store the current file path and timestamp for re-import purposes
		// @todo AssetImportData make a data class for Apex destructible assets
		DestructibleMesh->AssetImportData = NewObject<UAssetImportData>(DestructibleMesh);
		DestructibleMesh->AssetImportData->Update(UFactory::CurrentFilename);
		DestructibleMesh->AssetImportData->bDirty = false;
	}

	DestructibleMesh->PreEditChange(NULL);

	// Build FractureSettings from ApexDestructibleAsset in case we want to re-fracture
#if WITH_EDITORONLY_DATA
	DestructibleMesh->CreateFractureSettings();
	DestructibleMesh->FractureSettings->BuildRootMeshFromApexDestructibleAsset(ApexDestructibleAsset, Options);
	// Fill materials
	DestructibleMesh->FractureSettings->Materials.Reset(DestructibleMesh->Materials.Num());
	for (int32 MaterialIndex = 0; MaterialIndex < DestructibleMesh->Materials.Num(); ++MaterialIndex)
	{
		DestructibleMesh->FractureSettings->Materials.Insert(DestructibleMesh->Materials[MaterialIndex].MaterialInterface, MaterialIndex);
	}
#endif	// WITH_EDITORONLY_DATA

	if (!SetApexDestructibleAsset(*DestructibleMesh, ApexDestructibleAsset, OutData, Options))
	{
		// should remove this destructible mesh. if not, this object causes a crash when ticking because it doesn't have proper rendering resources
		// @TODO : creates this destructible mesh after loading data completely
		DestructibleMesh->PostEditChange();
		DestructibleMesh->ConditionalBeginDestroy();
		return NULL;
	}

	return DestructibleMesh;
}
UDestructibleMesh* ImportDestructibleMeshFromApexDestructibleAsset(UObject* InParent, NxDestructibleAsset& ApexDestructibleAsset, FName Name, EObjectFlags Flags, FSkeletalMeshImportData* OutData, EImportOptions::Type Options)
{
	// The APEX Destructible Asset contains an APEX Render Mesh Asset, get a pointer to this
	const physx::NxRenderMeshAsset* ApexRenderMesh = ApexDestructibleAsset.getRenderMeshAsset();
	if (ApexRenderMesh == NULL)
	{
		return NULL;
	}

	// Number of submeshes (aka "elements" in Unreal)
	const physx::PxU32 SubmeshCount = ApexRenderMesh->getSubmeshCount();
	if (SubmeshCount == 0)
	{
		return NULL;
	}

	// Make sure rendering is done - so we are not changing data being used by collision drawing.
	FlushRenderingCommands();

	UDestructibleMesh* DestructibleMesh = FindObject<UDestructibleMesh>(InParent, *Name.ToString());
	if (DestructibleMesh == NULL)
	{
		// Create the new UDestructibleMesh object if the one with the same name does not exist
		DestructibleMesh = CastChecked<UDestructibleMesh>(StaticConstructObject(UDestructibleMesh::StaticClass(), InParent, Name, Flags));
	}
	
	if (!(Options & EImportOptions::PreserveSettings))
	{
		// Store the current file path and timestamp for re-import purposes
		// @todo AssetImportData make a data class for Apex destructible assets
		DestructibleMesh->AssetImportData = ConstructObject<UAssetImportData>(UAssetImportData::StaticClass(), DestructibleMesh);
		DestructibleMesh->AssetImportData->SourceFilePath = FReimportManager::SanitizeImportFilename(UFactory::CurrentFilename, DestructibleMesh);
		DestructibleMesh->AssetImportData->SourceFileTimestamp = IFileManager::Get().GetTimeStamp(*UFactory::CurrentFilename).ToString();
	}

	DestructibleMesh->PreEditChange(NULL);

	// Build FractureSettings from ApexDestructibleAsset in case we want to re-fracture
#if WITH_EDITORONLY_DATA
	DestructibleMesh->CreateFractureSettings();
	DestructibleMesh->FractureSettings->BuildRootMeshFromApexDestructibleAsset(ApexDestructibleAsset, Options);
	// Fill materials
	DestructibleMesh->FractureSettings->Materials.Reset(DestructibleMesh->Materials.Num());
	for (int32 MaterialIndex = 0; MaterialIndex < DestructibleMesh->Materials.Num(); ++MaterialIndex)
	{
		DestructibleMesh->FractureSettings->Materials.Insert(DestructibleMesh->Materials[MaterialIndex].MaterialInterface, MaterialIndex);
	}
#endif	// WITH_EDITORONLY_DATA

	if (!SetApexDestructibleAsset(*DestructibleMesh, ApexDestructibleAsset, OutData, Options))
	{
		return NULL;
	}

	return DestructibleMesh;
}