2019-12-26 23:01:54 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-10-04 13:11:45 -04:00
# include "DatasmithMaxWriter.h"
# include "DatasmithMaxClassIDs.h"
# include "MaxMaterialsToUEPbr/DatasmithMaxMaterialsToUEPbr.h"
# include "DatasmithExportOptions.h"
# include "DatasmithSceneFactory.h"
2024-03-27 03:26:43 -04:00
# include "DatasmithMaxSceneHelper.h"
2019-10-04 13:11:45 -04:00
# include "DatasmithMaxLogger.h"
# include "Misc/Paths.h"
# include "Windows/AllowWindowsPlatformTypes.h"
MAX_INCLUDES_START
# include "bitmap.h"
# include "xref/iXrefMaterial.h"
MAX_INCLUDES_END
# include "Windows/HideWindowsPlatformTypes.h"
FString FDatasmithMaxMatWriter : : TextureSuffix = TEXT ( " _Tex " ) ;
FString FDatasmithMaxMatWriter : : TextureBakeFormat = TEXT ( " .tga " ) ;
bool FDatasmithMaxMatHelper : : HasNonBakeableSubmap ( Texmap * InTexmap )
{
if ( InTexmap = = NULL )
{
return false ;
}
// Skip any view dependent TexMap
// Having a THIRDPARTYMULTITEXCLASS as an input for a color correction node crashes when calling RenderBitmap on the color correction texmap so skip it.
if ( InTexmap - > ClassID ( ) = = VRAYDIRTCLASS | | InTexmap - > ClassID ( ) = = CORONAAOCLASS | | InTexmap - > ClassID ( ) = = FALLOFFCLASS | | InTexmap - > ClassID ( ) = = THIRDPARTYMULTITEXCLASS )
{
return true ;
}
if ( InTexmap - > ClassID ( ) = = RBITMAPCLASS )
{
StdUVGen * UV = ( ( BitmapTex * ) InTexmap ) - > GetUVGen ( ) ;
if ( UV = = NULL )
{
return true ;
}
float U = UV - > GetUScl ( GetCOREInterface ( ) - > GetTime ( ) ) ;
float V = UV - > GetVScl ( GetCOREInterface ( ) - > GetTime ( ) ) ;
float IntegralPart ;
if ( U > 10.f | | V > 10.f | | FMath : : IsNearlyEqual ( FMath : : Modf ( U , & IntegralPart ) , 0.f ) = = false | | FMath : : IsNearlyEqual ( FMath : : Modf ( V , & IntegralPart ) , 0.f ) = = false )
{
return true ;
}
}
for ( int SubMap = 0 ; SubMap < InTexmap - > NumSubTexmaps ( ) ; SubMap + + )
{
if ( InTexmap - > SubTexmapOn ( SubMap ) ! = 0 & & HasNonBakeableSubmap ( InTexmap - > GetSubTexmap ( SubMap ) ) = = true )
{
return true ;
}
}
return false ;
}
EDSBitmapType FDatasmithMaxMatHelper : : GetTextureClass ( Texmap * InTexMap )
{
EDSBitmapType Type = EDSBitmapType : : NotSupported ;
if ( InTexMap ! = nullptr )
{
2020-02-17 14:07:50 -05:00
MSTR ClassName ;
InTexMap - > GetClassName ( ClassName ) ;
2019-10-04 13:11:45 -04:00
if ( InTexMap - > ClassID ( ) = = RBITMAPCLASS )
{
Type = EDSBitmapType : : RegularBitmap ;
}
2020-02-17 14:07:50 -05:00
//Somehow, there are multiple autodesk map classes using the same ClassID, we only support Autodesk Bitmap.
else if ( InTexMap - > ClassID ( ) = = AUTODESKBITMAPCLASS & & FCString : : Stricmp ( ClassName , TEXT ( " Autodesk Bitmap " ) ) = = 0 )
2019-10-04 13:11:45 -04:00
{
Type = EDSBitmapType : : AutodeskBitmap ;
}
else if ( InTexMap - > ClassID ( ) = = THEABITMAPCLASS )
{
Type = EDSBitmapType : : TheaBitmap ;
}
else if ( InTexMap - > ClassID ( ) = = REGULARNORMALCLASS )
{
Type = EDSBitmapType : : NormalMap ;
}
else if ( InTexMap - > ClassID ( ) = = VRAYNORMALCLASS )
{
Type = EDSBitmapType : : NormalMap ;
}
else if ( InTexMap - > ClassID ( ) = = CORONANORMALCLASS )
{
Type = EDSBitmapType : : NormalMap ;
}
else if ( InTexMap - > ClassID ( ) = = COLORCORRECTCLASS )
{
if ( FDatasmithMaxMatHelper : : HasNonBakeableSubmap ( InTexMap ) = = false )
{
Type = EDSBitmapType : : BakeableMap ;
}
else
{
Type = EDSBitmapType : : ColorCorrector ;
}
}
else if ( InTexMap - > ClassID ( ) = = FALLOFFCLASS )
{
Type = EDSBitmapType : : FallOff ;
}
else if ( InTexMap - > ClassID ( ) = = MIXCLASS )
{
if ( FDatasmithMaxMatHelper : : HasNonBakeableSubmap ( InTexMap ) = = false )
{
Type = EDSBitmapType : : BakeableMap ;
}
else
{
Type = EDSBitmapType : : Mix ;
}
}
else if ( InTexMap - > ClassID ( ) = = NOISECLASS )
{
Type = EDSBitmapType : : Noise ;
}
else if ( InTexMap - > ClassID ( ) = = GRADIENTCLASS )
{
if ( FDatasmithMaxMatHelper : : HasNonBakeableSubmap ( InTexMap ) = = false )
{
Type = EDSBitmapType : : BakeableMap ;
}
else
{
Type = EDSBitmapType : : Gradient ;
}
}
else if ( InTexMap - > ClassID ( ) = = GRADIENTRAMPCLASS )
{
if ( FDatasmithMaxMatHelper : : HasNonBakeableSubmap ( InTexMap ) = = false )
{
Type = EDSBitmapType : : BakeableMap ;
}
}
else if ( InTexMap - > ClassID ( ) = = CHECKERCLASS )
{
if ( FDatasmithMaxMatHelper : : HasNonBakeableSubmap ( InTexMap ) = = false )
{
Type = EDSBitmapType : : BakeableMap ;
}
else
{
Type = EDSBitmapType : : Checker ;
}
}
else if ( InTexMap - > ClassID ( ) = = CELLULARCLASS )
{
Type = EDSBitmapType : : Cellular ;
}
else if ( InTexMap - > ClassID ( ) = = VRAYDIRTCLASS )
{
Type = EDSBitmapType : : VRayDirt ;
}
else if ( InTexMap - > ClassID ( ) = = COMPOSITETEXCLASS )
{
Type = EDSBitmapType : : CompositeTex ;
}
else if ( InTexMap - > ClassID ( ) = = CORONABITMAPCLASS )
{
Type = EDSBitmapType : : CoronaBitmap ;
}
else if ( InTexMap - > ClassID ( ) = = VRAYHDRICLASS )
{
Type = EDSBitmapType : : VRayHRDI ;
}
else if ( InTexMap - > ClassID ( ) = = CORONACOLORCLASS )
{
Type = EDSBitmapType : : CoronaColor ;
}
else if ( InTexMap - > ClassID ( ) = = CORONAMIXCLASS )
{
Type = EDSBitmapType : : CoronaMix ;
}
else if ( InTexMap - > ClassID ( ) = = CORONAMULTITEXCLASS )
{
Type = EDSBitmapType : : CoronaMultiTex ;
}
else if ( InTexMap - > ClassID ( ) = = CORONAAOCLASS )
{
Type = EDSBitmapType : : CoronaAO ;
}
else if ( InTexMap - > ClassID ( ) = = VRAYCOLORCLASS )
{
Type = EDSBitmapType : : VRayColor ;
}
else if ( InTexMap - > ClassID ( ) = = THIRDPARTYMULTITEXCLASS )
{
Type = EDSBitmapType : : ThirdPartyMultiTex ;
}
else if ( InTexMap - > ClassID ( ) = = CORONAPHYSICALSKYCLASS )
{
Type = EDSBitmapType : : PhysicalSky ;
}
else if ( InTexMap - > ClassID ( ) = = VRAYPHYSICALSKYCLASS )
{
Type = EDSBitmapType : : PhysicalSky ;
}
else if ( InTexMap - > ClassID ( ) = = MRPHYSICALSKYCLASS )
{
Type = EDSBitmapType : : PhysicalSky ;
}
else if ( InTexMap - > ClassID ( ) = = MRPHYSICALSKYBCLASS )
{
Type = EDSBitmapType : : PhysicalSky ;
}
else if ( InTexMap - > ClassID ( ) = = TILESMAPCLASS )
{
if ( FDatasmithMaxMatHelper : : HasNonBakeableSubmap ( InTexMap ) = = false )
{
Type = EDSBitmapType : : BakeableMap ;
}
}
}
return Type ;
}
EDSMaterialType FDatasmithMaxMatHelper : : GetMaterialClass ( Mtl * Material )
{
EDSMaterialType Type = EDSMaterialType : : NotSupported ;
if ( Material ! = nullptr )
{
if ( Material - > ClassID ( ) = = THEAMATOLDCLASS )
{
Type = EDSMaterialType : : TheaMaterialDeprecated ;
}
else if ( Material - > ClassID ( ) = = THEARANDOMCLASS )
{
Type = EDSMaterialType : : TheaRandom ;
}
else if ( Material - > ClassID ( ) = = THEAMATERIALCLASS )
{
Type = EDSMaterialType : : TheaMaterial ;
}
else if ( Material - > ClassID ( ) = = THEABASICCLASS )
{
Type = EDSMaterialType : : TheaBasic ;
}
else if ( Material - > ClassID ( ) = = THEAGLOSSYCLASS )
{
Type = EDSMaterialType : : TheaGlossy ;
}
else if ( Material - > ClassID ( ) = = THEASSSCLASS )
{
Type = EDSMaterialType : : TheaSSS ;
}
else if ( Material - > ClassID ( ) = = THEAFILMCLASS )
{
Type = EDSMaterialType : : TheaFilm ;
}
else if ( Material - > ClassID ( ) = = THEACOATINGCLASS )
{
Type = EDSMaterialType : : TheaCoating ;
}
else if ( Material - > ClassID ( ) = = MULTIMAT_CLASS_ID )
{
Type = EDSMaterialType : : MultiMat ;
}
else if ( Material - > ClassID ( ) = = STANDARDMATCLASS )
{
Type = EDSMaterialType : : StandardMat ;
}
else if ( Material - > ClassID ( ) = = SHELLCLASS )
{
Type = EDSMaterialType : : ShellMat ;
}
else if ( Material - > ClassID ( ) = = BLENDMATCLASS )
{
Type = EDSMaterialType : : BlendMat ;
}
else if ( Material - > ClassID ( ) = = XREFMATCLASS )
{
Type = EDSMaterialType : : XRefMat ;
}
else if ( Material - > ClassID ( ) = = ARCHDESIGNMATCLASS )
{
Type = EDSMaterialType : : ArchDesignMat ;
}
else if ( Material - > ClassID ( ) = = VRAYMATCLASS )
{
Type = EDSMaterialType : : VRayMat ;
}
else if ( Material - > ClassID ( ) = = VRAYBLENDMATCLASS )
{
Type = EDSMaterialType : : VRayBlendMat ;
}
else if ( Material - > ClassID ( ) = = VRAYLIGHTMATCLASS )
{
Type = EDSMaterialType : : VRayLightMat ;
}
else if ( Material - > ClassID ( ) = = VRAYFASTSSSCLASS )
{
Type = EDSMaterialType : : VRayFastSSSMat ;
}
else if ( Material - > ClassID ( ) = = CORONAMATCLASS )
{
Type = EDSMaterialType : : CoronaMat ;
}
else if ( Material - > ClassID ( ) = = CORONALAYERMATCLASS )
{
Type = EDSMaterialType : : CoronaLayerMat ;
}
else if ( Material - > ClassID ( ) = = CORONALIGHTMATCLASS )
{
Type = EDSMaterialType : : CoronaLightMat ;
}
else if ( Material - > ClassID ( ) = = PHYSICALMATCLASS )
{
Type = EDSMaterialType : : PhysicalMat ;
}
}
return Type ;
}
Mtl * FDatasmithMaxMatHelper : : GetRenderedXRefMaterial ( Mtl * Material )
{
const TimeValue CurrentTime = GetCOREInterface ( ) - > GetTime ( ) ;
const int NumParamBlocks = Material - > NumParamBlocks ( ) ;
bool bSourceMaterialOverridden = false ;
Mtl * MaterialOverride = nullptr ;
for ( int j = 0 ; j < NumParamBlocks ; j + + )
{
IParamBlock2 * ParamBlock2 = Material - > GetParamBlockByID ( ( short ) j ) ;
ParamBlockDesc2 * ParamBlockDesc = ParamBlock2 - > GetDesc ( ) ;
for ( int i = 0 ; i < ParamBlockDesc - > count ; i + + )
{
const ParamDef & ParamDefinition = ParamBlockDesc - > paramdefs [ i ] ;
// Diffuse
if ( FCString : : Stricmp ( ParamDefinition . int_name , TEXT ( " enableOverride " ) ) = = 0 )
{
bSourceMaterialOverridden = ParamBlock2 - > GetInt ( ParamDefinition . ID , CurrentTime ) ! = 0 ;
}
else if ( FCString : : Stricmp ( ParamDefinition . int_name , TEXT ( " overrideMaterial " ) ) = = 0 )
{
MaterialOverride = ParamBlock2 - > GetMtl ( ParamDefinition . ID , CurrentTime ) ;
}
}
ParamBlock2 - > ReleaseDesc ( ) ;
}
Mtl * RenderedMaterial = nullptr ;
if ( bSourceMaterialOverridden )
{
RenderedMaterial = MaterialOverride ;
}
else
{
IXRefMaterial * XRefMaterial = static_cast < IXRefMaterial * > ( Material ) ;
RenderedMaterial = XRefMaterial - > GetSourceMaterial ( true ) ;
}
return RenderedMaterial ;
}
FLinearColor FDatasmithMaxMatHelper : : MaxColorToFLinearColor ( BMM_Color_fl Color , float Multiplier /*= 1.0f*/ )
{
Color . r = FMath : : Pow ( Color . r , 1.0f / FDatasmithExportOptions : : ColorGamma ) ;
Color . g = FMath : : Pow ( Color . g , 1.0f / FDatasmithExportOptions : : ColorGamma ) ;
Color . b = FMath : : Pow ( Color . b , 1.0f / FDatasmithExportOptions : : ColorGamma ) ;
float Red = Color . r * Multiplier ;
float Green = Color . g * Multiplier ;
float Blue = Color . b * Multiplier ;
return FLinearColor ( Red , Green , Blue ) ;
}
FLinearColor FDatasmithMaxMatHelper : : MaxLinearColorToFLinearColor ( BMM_Color_fl Color , float Multiplier /*= 1.0f*/ )
{
return FLinearColor ( Color . r , Color . g , Color . b ) ;
}
float FDatasmithMaxMatHelper : : GetBitmapGamma ( BitmapTex * InBitmapTex )
{
if ( InBitmapTex )
{
if ( Bitmap * ActualBitmap = InBitmapTex - > GetBitmap ( GetCOREInterface ( ) - > GetTime ( ) ) )
{
return ActualBitmap - > Gamma ( ) ;
}
}
return 2.2f ;
}
float FDatasmithMaxMatHelper : : GetBitmapGamma ( BitmapInfo * InBitmap )
{
if ( InBitmap )
{
return InBitmap - > Gamma ( ) ;
}
return 2.2f ;
}
bool FDatasmithMaxMatHelper : : IsSRGB ( BitmapTex & InBitmapTex )
{
if ( Bitmap * ActualBitmap = InBitmapTex . GetBitmap ( GetCOREInterface ( ) - > GetTime ( ) ) )
{
return IsSRGB ( * ActualBitmap ) ;
}
return true ;
}
bool FDatasmithMaxMatHelper : : IsSRGB ( Bitmap & InBitmap )
{
if ( InBitmap . IsHighDynamicRange ( ) )
{
return false ;
}
# ifdef MAX_RELEASE_R19
BitmapInfo BitmapInformation = InBitmap . GetBitmapInfo ( ) ;
switch ( BitmapInformation . Type ( ) )
{
// UE considers that all bit depth >= 16 are linear
case BMM_GRAY_16 :
case BMM_FLOAT_RGBA_32 :
case BMM_FLOAT_GRAY_32 :
case BMM_REALPIX_32 :
case BMM_TRUE_48 :
case BMM_TRUE_64 :
return false ; // Linear
break ;
default :
return true ; // sRGB
break ;
}
# endif // MAX_RELEASE_R19
return true ;
}
bool FDatasmithMaxMatExport : : UseFirstSubMapOnly ( EDSMaterialType MaterialType , Mtl * Material )
{
switch ( MaterialType )
{
case EDSMaterialType : : TheaMaterial :
case EDSMaterialType : : MultiMat :
case EDSMaterialType : : StandardMat :
case EDSMaterialType : : ArchDesignMat :
case EDSMaterialType : : VRayMat :
case EDSMaterialType : : VRayLightMat :
case EDSMaterialType : : CoronaMat :
case EDSMaterialType : : CoronaLightMat :
case EDSMaterialType : : BlendMat :
case EDSMaterialType : : XRefMat :
case EDSMaterialType : : VRayBlendMat :
case EDSMaterialType : : CoronaLayerMat :
return false ;
default :
if ( Material - > NumSubMtls ( ) < 1 )
{
return false ;
}
else
{
return true ;
}
}
}
TSharedPtr < IDatasmithBaseMaterialElement > FDatasmithMaxMatExport : : ExportUniqueMaterial ( TSharedRef < IDatasmithScene > DatasmithScene , Mtl * Material , const TCHAR * AssetsPath )
{
2022-06-10 12:47:33 -04:00
if ( ! Material )
2019-10-04 13:11:45 -04:00
{
2022-06-10 12:47:33 -04:00
return { } ;
2021-09-22 10:21:10 -04:00
}
2022-06-10 12:47:33 -04:00
FString MaterialName ( FDatasmithMaxMaterialsToUEPbrManager : : GetDatasmithMaterialName ( Material ) ) ;
for ( int i = 0 ; i < DatasmithScene - > GetMaterialsCount ( ) ; i + + )
2021-09-22 10:21:10 -04:00
{
2022-06-10 12:47:33 -04:00
if ( FString ( DatasmithScene - > GetMaterial ( i ) - > GetName ( ) ) = = MaterialName )
2021-09-22 10:21:10 -04:00
{
2022-06-10 12:47:33 -04:00
return DatasmithScene - > GetMaterial ( i ) ;
2019-10-04 13:11:45 -04:00
}
}
if ( FDatasmithMaxMaterialsToUEPbr * MaterialConverter = FDatasmithMaxMaterialsToUEPbrManager : : GetMaterialConverter ( Material ) )
{
TSharedPtr < IDatasmithBaseMaterialElement > UEPbrMaterial ;
MaterialConverter - > Convert ( DatasmithScene , UEPbrMaterial , Material , AssetsPath ) ;
2022-06-10 12:47:33 -04:00
FDatasmithMaxMaterialsToUEPbrManager : : AddDatasmithMaterial ( DatasmithScene , Material , UEPbrMaterial ) ;
2019-10-04 13:11:45 -04:00
return UEPbrMaterial ;
}
else
{
2022-06-10 12:47:33 -04:00
TSharedRef < IDatasmithMaterialElement > MaterialElement = FDatasmithSceneFactory : : CreateMaterial ( * MaterialName ) ;
FDatasmithMaxMaterialsToUEPbrManager : : AddDatasmithMaterial ( DatasmithScene , Material , MaterialElement ) ;
2019-10-04 13:11:45 -04:00
WriteXMLMaterial ( DatasmithScene , MaterialElement , Material ) ;
return MaterialElement ;
}
}
void FDatasmithMaxMatExport : : WriteXMLMaterial ( TSharedRef < IDatasmithScene > DatasmithScene , TSharedPtr < IDatasmithMaterialElement > MaterialElement , Mtl * Material )
{
if ( Material = = nullptr )
{
return ;
}
EDSMaterialType MaterialType = FDatasmithMaxMatHelper : : GetMaterialClass ( Material ) ;
switch ( FDatasmithMaxMatHelper : : GetMaterialClass ( Material ) )
{
case EDSMaterialType : : StandardMat :
FDatasmithMaxMatWriter : : ExportStandardMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : TheaMaterial :
FDatasmithMaxMatWriter : : ExportTheaMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : VRayMat :
FDatasmithMaxMatWriter : : ExportVRayMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : VRayLightMat :
FDatasmithMaxMatWriter : : ExportVRayLightMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : ArchDesignMat :
FDatasmithMaxMatWriter : : ExportArchDesignMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : CoronaMat :
FDatasmithMaxMatWriter : : ExportCoronaMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : CoronaLightMat :
FDatasmithMaxMatWriter : : ExportCoronaLightMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : BlendMat :
FDatasmithMaxMatWriter : : ExportBlendMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : XRefMat :
FDatasmithMaxMatExport : : WriteXMLMaterial ( DatasmithScene , MaterialElement , FDatasmithMaxMatHelper : : GetRenderedXRefMaterial ( Material ) ) ;
break ;
case EDSMaterialType : : VRayBlendMat :
FDatasmithMaxMatWriter : : ExportVrayBlendMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : CoronaLayerMat :
FDatasmithMaxMatWriter : : ExportCoronaBlendMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : PhysicalMat :
FDatasmithMaxMatWriter : : ExportPhysicalMaterial ( DatasmithScene , MaterialElement , Material ) ;
break ;
case EDSMaterialType : : TheaRandom :
return ; // already added!
break ;
default :
if ( UseFirstSubMapOnly ( MaterialType , Material ) = = false )
{
DatasmithMaxLogger : : Get ( ) . AddUnsupportedMat ( Material ) ;
}
else
{
DatasmithMaxLogger : : Get ( ) . AddPartialSupportedMat ( Material ) ;
FDatasmithMaxMatExport : : WriteXMLMaterial ( DatasmithScene , MaterialElement , Material - > GetSubMtl ( 0 ) ) ;
}
break ;
}
}
FString FDatasmithMaxMatWriter : : DumpTexture ( TSharedRef < IDatasmithScene > DatasmithScene , TSharedPtr < IDatasmithCompositeTexture > & CompTex , Texmap * InTexmap , const TCHAR * Prefix , const TCHAR * ColorPrefix , bool bForceInvert , bool bIsGrayscale )
{
if ( InTexmap = = NULL )
{
return TEXT ( " " ) ;
}
// if it is not a regular one it should be nested.
if ( CompTex - > GetMode ( ) ! = EDatasmithCompMode : : Regular )
{
TSharedPtr < IDatasmithCompositeTexture > ChildCompTex = FDatasmithSceneFactory : : CreateCompositeTexture ( ) ;
FString Result = DumpTexture ( DatasmithScene , ChildCompTex , InTexmap , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
CompTex - > AddSurface ( ChildCompTex ) ;
return Result ;
}
EDSBitmapType TextureClass = FDatasmithMaxMatHelper : : GetTextureClass ( InTexmap ) ;
if ( FString ( Prefix ) = = DATASMITH_BUMPTEXNAME & & TextureClass ! = EDSBitmapType : : NormalMap )
{
DatasmithMaxLogger : : Get ( ) . AddTextureError ( TEXT ( " Bump maps are automatically converted to normal maps, as Unreal Engine does not handle bump maps directly. " ) ) ;
}
switch ( TextureClass )
{
case EDSBitmapType : : RegularBitmap :
{
return DumpBitmap ( CompTex , ( BitmapTex * ) InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : AutodeskBitmap :
{
return DumpAutodeskBitmap ( CompTex , InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : TheaBitmap :
{
return DumpBitmapThea ( CompTex , ( BitmapTex * ) InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : CoronaBitmap :
{
return DumpBitmapCorona ( CompTex , ( BitmapTex * ) InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : VRayHRDI :
{
return DumpVrayHdri ( CompTex , ( BitmapTex * ) InTexmap , Prefix , bForceInvert ) ;
}
case EDSBitmapType : : ColorCorrector :
{
if ( FDatasmithMaxMatHelper : : HasNonBakeableSubmap ( InTexmap ) = = false )
{
return DumpBakeable ( CompTex , ( BitmapTex * ) InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorCorrect ( DatasmithScene , CompTex , InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
}
case EDSBitmapType : : Gradient :
{
DatasmithMaxLogger : : Get ( ) . AddPartialSupportedMap ( InTexmap ) ;
if ( InTexmap - > GetSubTexmap ( 0 ) ! = NULL )
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 0 ) , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " color1 " ) ) ;
}
}
case EDSBitmapType : : GradientRamp :
{
DatasmithMaxLogger : : Get ( ) . AddPartialSupportedMap ( InTexmap ) ;
if ( InTexmap - > GetSubTexmap ( 0 ) ! = NULL )
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 0 ) , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " color1 " ) ) ;
}
}
case EDSBitmapType : : Checker :
{
DatasmithMaxLogger : : Get ( ) . AddPartialSupportedMap ( InTexmap ) ;
if ( InTexmap - > GetSubTexmap ( 0 ) ! = NULL )
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 0 ) , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " color1 " ) ) ;
}
}
case EDSBitmapType : : Cellular :
{
DatasmithMaxLogger : : Get ( ) . AddPartialSupportedMap ( InTexmap ) ;
if ( InTexmap - > GetSubTexmap ( 0 ) ! = NULL )
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 0 ) , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " cellColor " ) ) ;
}
}
case EDSBitmapType : : FallOff :
{
return DumpFalloff ( DatasmithScene , CompTex , InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : Mix :
{
return DumpMix ( DatasmithScene , CompTex , InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : CompositeTex :
{
return DumpCompositetex ( DatasmithScene , CompTex , InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : NormalMap :
{
return DumpNormalTexture ( DatasmithScene , CompTex , InTexmap , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : Noise :
{
DatasmithMaxLogger : : Get ( ) . AddPartialSupportedMap ( InTexmap ) ;
if ( InTexmap - > GetSubTexmap ( 0 ) ! = NULL )
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 0 ) , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " color1 " ) ) ;
}
}
case EDSBitmapType : : VRayDirt :
{
DatasmithMaxLogger : : Get ( ) . AddTextureError ( TEXT ( " V-Ray dirt texture is not supported and only the unoccluded texture/color will be used " ) ) ;
if ( InTexmap - > GetSubTexmap ( 0 ) ! = NULL )
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 0 ) , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " unoccluded_color " ) ) ;
}
}
case EDSBitmapType : : CoronaAO :
{
DatasmithMaxLogger : : Get ( ) . AddGeneralError ( TEXT ( " CoronaAO texture is not supported and only the unoccluded texture/color will be used " ) ) ;
if ( InTexmap - > GetSubTexmap ( 1 ) ! = NULL )
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 1 ) , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " colorUnoccluded " ) ) ;
}
}
case EDSBitmapType : : VRayColor :
{
return DumpVrayColor ( CompTex , InTexmap , Prefix , bForceInvert ) ;
}
case EDSBitmapType : : CoronaColor :
{
return DumpCoronaColor ( CompTex , InTexmap , Prefix , bForceInvert ) ;
}
case EDSBitmapType : : CoronaMix :
{
return DumpCoronaMix ( DatasmithScene , CompTex , InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : CoronaMultiTex :
{
DatasmithMaxLogger : : Get ( ) . AddPartialSupportedMap ( InTexmap ) ;
return DumpCoronaMultitex ( DatasmithScene , CompTex , InTexmap , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
case EDSBitmapType : : PhysicalSky :
{
DatasmithScene - > SetUsePhysicalSky ( true ) ;
return TEXT ( " " ) ;
}
case EDSBitmapType : : ThirdPartyMultiTex :
{
DatasmithMaxLogger : : Get ( ) . AddPartialSupportedMap ( InTexmap ) ;
if ( InTexmap - > GetSubTexmap ( 0 ) ! = NULL )
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 0 ) , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " sub_color " ) ) ;
}
}
case EDSBitmapType : : BakeableMap :
{
if ( FDatasmithMaxMatHelper : : HasNonBakeableSubmap ( InTexmap ) = = false )
{
return DumpBakeable ( CompTex , ( BitmapTex * ) InTexmap , Prefix , bForceInvert , bIsGrayscale ) ;
}
}
default :
{
if ( InTexmap - > NumSubTexmaps ( ) > 0 )
{
DatasmithMaxLogger : : Get ( ) . AddUnsupportedMap ( InTexmap ) ;
// just for try!
if ( InTexmap - > GetSubTexmap ( 0 ) ! = NULL )
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 0 ) , Prefix , ColorPrefix , bForceInvert , bIsGrayscale ) ;
}
else
{
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " color1 " ) ) ;
}
}
else
{
DatasmithMaxLogger : : Get ( ) . AddUnsupportedMap ( InTexmap ) ;
return DumpColorOfTexmap ( CompTex , InTexmap , ColorPrefix , TEXT ( " color1 " ) ) ;
}
}
}
}
FString FDatasmithMaxMatWriter : : DumpNormalTexture ( TSharedRef < IDatasmithScene > DatasmithScene , TSharedPtr < IDatasmithCompositeTexture > & CompTex , Texmap * InTexmap , const TCHAR * Prefix , const TCHAR * ColorPrefix , bool bForceInvert , bool bIsGrayscale )
{
int NumParamBlocks = InTexmap - > NumParamBlocks ( ) ;
bool bInvertGreen = false ;
for ( int j = 0 ; j < NumParamBlocks ; j + + )
{
IParamBlock2 * ParamBlock2 = InTexmap - > GetParamBlockByID ( ( short ) j ) ;
// The the descriptor to 'decode'
ParamBlockDesc2 * ParamBlockDesc = ParamBlock2 - > GetDesc ( ) ;
// Loop through all the defined parameters therein
for ( int i = 0 ; i < ParamBlockDesc - > count ; i + + )
{
const ParamDef & ParamDefinition = ParamBlockDesc - > paramdefs [ i ] ;
if ( FCString : : Stricmp ( ParamDefinition . int_name , TEXT ( " flip_green " ) ) = = 0 | | FCString : : Stricmp ( ParamDefinition . int_name , TEXT ( " flipgreen " ) ) = = 0 )
{
if ( ParamBlock2 - > GetInt ( ParamDefinition . ID , GetCOREInterface ( ) - > GetTime ( ) ) = = 1 )
{
bInvertGreen = true ;
}
continue ;
}
if ( FCString : : Stricmp ( ParamDefinition . int_name , TEXT ( " complement_ddl " ) ) = = 0 )
{
if ( ParamBlock2 - > GetInt ( ParamDefinition . ID , GetCOREInterface ( ) - > GetTime ( ) ) = = 4 )
{
bInvertGreen = false ;
}
else
{
bInvertGreen = true ;
}
continue ;
}
}
}
EDSBitmapType TextureClass = FDatasmithMaxMatHelper : : GetTextureClass ( InTexmap ) ;
if ( TextureClass = = EDSBitmapType : : NormalMap )
{
if ( FString ( Prefix ) ! = DATASMITH_BUMPTEXNAME )
{
FString DumpName = DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 0 ) , Prefix , ColorPrefix , bForceInvert | | bInvertGreen , bIsGrayscale ) ;
TSharedPtr < IDatasmithTextureElement > TextureElement ;
for ( int TextureIndex = 0 ; TextureIndex < DatasmithScene - > GetTexturesCount ( ) ; TextureIndex + + )
{
if ( DumpName = = DatasmithScene - > GetTexture ( TextureIndex ) - > GetName ( ) )
{
TextureElement = DatasmithScene - > GetTexture ( TextureIndex ) ;
}
}
if ( TextureElement )
{
// Only process the TextureElement once (we assume that the "Other" TextureMode means that it hasn't been processed yet)
if ( TextureElement - > GetTextureMode ( ) = = EDatasmithTextureMode : : Other )
{
if ( bInvertGreen )
{
TextureElement - > SetTextureMode ( EDatasmithTextureMode : : NormalGreenInv ) ;
}
else
{
TextureElement - > SetTextureMode ( EDatasmithTextureMode : : Normal ) ;
}
float RgbCurve = TextureElement - > GetRGBCurve ( ) ;
// if RgbCurve <= 0 it has been set to default mode so we can forget about that
// this happens mostly when no advanced gamma correction is enabled in 3dsmax preferences
if ( RgbCurve > 0.f )
{
if ( FDatasmithMaxMatWriter : : GetCoronaFixNormal ( InTexmap ) = = true )
{
// corona has a checkbox to work in automatic mode
RgbCurve = - 1.f ;
}
else
{
// Bitmaps are by default using Gamma/2.2f RGB curve but the reference for normalmaps
// should be Gamma/1.0f
// if the user has set the proper value (1.0) the result will be 2.2/2.2 = 1.0
RgbCurve * = 2.2f ;
}
TextureElement - > SetRGBCurve ( RgbCurve ) ;
if ( FMath : : IsNearlyEqual ( RgbCurve , 1.0f , 0.001f ) = = false & & RgbCurve > 0.0f )
{
FString Error = FString ( " Potential wrong input gamma on normalmap: " ) + FPaths : : GetCleanFilename ( TextureElement - > GetFile ( ) ) ;
DatasmithMaxLogger : : Get ( ) . AddTextureError ( * Error ) ;
}
}
}
}
return DumpName ;
}
else
{
return DumpTexture ( DatasmithScene , CompTex , InTexmap - > GetSubTexmap ( 1 ) , TEXT ( " " ) , TEXT ( " " ) , bForceInvert , bIsGrayscale ) ;
}
}
if ( TextureClass = = EDSBitmapType : : TheaBitmap )
{
return DumpBitmapThea ( CompTex , ( BitmapTex * ) InTexmap , Prefix , bForceInvert | | bInvertGreen , bIsGrayscale ) ;
}
return TEXT ( " " ) ;
}
void FDatasmithMaxMatWriter : : DumpWeightedTexture ( TSharedRef < IDatasmithScene > DatasmithScene , TSharedPtr < IDatasmithCompositeTexture > & CompTex , Texmap * InTexmap , BMM_Color_fl Color , float Weight , const TCHAR * Prefix , const TCHAR * ColorPrefix , bool bForceInvert , bool bIsGrayscale )
{
FString ActualPrefix = FString ( Prefix ) + FString ( TEXT ( " comp " ) ) ;
CompTex - > SetMode ( EDatasmithCompMode : : Mix ) ;
DumpTexture ( DatasmithScene , CompTex , InTexmap , DATASMITH_TEXTURENAME , DATASMITH_COLORNAME , bForceInvert , bIsGrayscale ) ;
CompTex - > AddSurface ( FDatasmithMaxMatHelper : : MaxColorToFLinearColor ( Color ) ) ;
CompTex - > AddParamVal1 ( IDatasmithCompositeTexture : : ParamVal ( 1.0f - ( float ) Weight , TEXT ( " Weight " ) ) ) ;
}
void FDatasmithMaxMatWriter : : DumpWeightedColor ( TSharedPtr < IDatasmithCompositeTexture > & CompTex , BMM_Color_fl ColorA , BMM_Color_fl ColorB , float Weight , const TCHAR * Prefix )
{
if ( Weight = = 1 )
{
CompTex - > AddSurface ( FDatasmithMaxMatHelper : : MaxColorToFLinearColor ( ColorA ) ) ;
return ;
}
if ( Weight = = 0 )
{
CompTex - > AddSurface ( FDatasmithMaxMatHelper : : MaxColorToFLinearColor ( ColorB ) ) ;
return ;
}
FString ActualPrefix = FString ( Prefix ) + FString ( TEXT ( " comp " ) ) ;
CompTex - > SetMode ( EDatasmithCompMode : : Mix ) ;
CompTex - > AddSurface ( FDatasmithMaxMatHelper : : MaxColorToFLinearColor ( ColorA ) ) ;
CompTex - > AddSurface ( FDatasmithMaxMatHelper : : MaxColorToFLinearColor ( ColorB ) ) ;
CompTex - > AddParamVal1 ( IDatasmithCompositeTexture : : ParamVal ( 1.0f - ( float ) Weight , TEXT ( " Weight " ) ) ) ;
}
FString FDatasmithMaxMatWriter : : DumpColorOfTexmap ( TSharedPtr < IDatasmithCompositeTexture > & CompTex , Texmap * InTexmap , const TCHAR * ColorPrefix , TCHAR * Property )
{
int NumParamBlocks = InTexmap - > NumParamBlocks ( ) ;
for ( int j = 0 ; j < NumParamBlocks ; j + + )
{
IParamBlock2 * ParamBlock2 = InTexmap - > GetParamBlockByID ( ( short ) j ) ;
if ( ParamBlock2 = = NULL )
{
return TEXT ( " " ) ;
}
// The the descriptor to 'decode'
ParamBlockDesc2 * ParamBlockDesc = ParamBlock2 - > GetDesc ( ) ;
if ( ParamBlockDesc = = NULL )
{
return TEXT ( " " ) ;
}
// Loop through all the defined parameters therein
for ( int i = 0 ; i < ParamBlockDesc - > count ; i + + )
{
const ParamDef & ParamDefinition = ParamBlockDesc - > paramdefs [ i ] ;
if ( FCString : : Stricmp ( ParamDefinition . int_name , Property ) = = 0 )
{
BMM_Color_fl Color = ( BMM_Color_fl ) ParamBlock2 - > GetColor ( ParamDefinition . ID , GetCOREInterface ( ) - > GetTime ( ) ) ;
CompTex - > AddSurface ( FDatasmithMaxMatHelper : : MaxColorToFLinearColor ( Color ) ) ;
return TEXT ( " " ) ;
}
}
ParamBlock2 - > ReleaseDesc ( ) ;
}
// not found using 'property', choose first color
for ( int j = 0 ; j < NumParamBlocks ; j + + )
{
IParamBlock2 * ParamBlock2 = InTexmap - > GetParamBlockByID ( ( short ) j ) ;
ParamBlockDesc2 * ParamBlockDesc = ParamBlock2 - > GetDesc ( ) ;
for ( int i = 0 ; i < ParamBlockDesc - > count ; i + + )
{
const ParamDef & ParamDefinition = ParamBlockDesc - > paramdefs [ i ] ;
BMM_Color_fl Color = ( BMM_Color_fl ) ParamBlock2 - > GetColor ( ParamDefinition . ID , GetCOREInterface ( ) - > GetTime ( ) ) ;
if ( Color . r ! = 0 | | Color . g ! = 0 | | Color . b ! = 0 )
{
CompTex - > AddSurface ( FDatasmithMaxMatHelper : : MaxColorToFLinearColor ( Color ) ) ;
return TEXT ( " " ) ;
}
}
ParamBlock2 - > ReleaseDesc ( ) ;
}
return TEXT ( " " ) ;
}