|
@@ -0,0 +1,2093 @@
|
|
|
+#include "assetImporter.h"
|
|
|
+#include "assetImporter_ScriptBinding.h"
|
|
|
+#include "core/strings/findMatch.h"
|
|
|
+#include "ImageAsset.h"
|
|
|
+#include "ShapeAsset.h"
|
|
|
+#include "SoundAsset.h"
|
|
|
+#include "MaterialAsset.h"
|
|
|
+#include "ShapeAnimationAsset.h"
|
|
|
+
|
|
|
+#include "ts/collada/colladaUtils.h"
|
|
|
+#include "ts/collada/colladaAppNode.h"
|
|
|
+#include "ts/collada/colladaShapeLoader.h"
|
|
|
+
|
|
|
+#include "ts/assimp/assimpShapeLoader.h"
|
|
|
+#include "ts/tsShapeConstruct.h"
|
|
|
+
|
|
|
+
|
|
|
+ConsoleDocClass(AssetImportConfig,
|
|
|
+ "@brief Defines properties for an AssetImprotConfig object.\n"
|
|
|
+ "@AssetImportConfig is a SimObject derived object intended to act as a container for all the necessary configuration data when running the Asset Importer.\n"
|
|
|
+ "@It dictates if and how any given asset type will be processed when running an import action. This is because the Asset Importer utilizes a lot of informed logic\n"
|
|
|
+ "@to try and automate as much of the import process as possible. In theory, you would run the import on a given file, and based on your config the importer will do\n"
|
|
|
+ "@everything from importing the designated file, as well as finding and importing any associated files such as images or materials, and prepping the objects at time\n"
|
|
|
+ "@of import to avoid as much manual post-processing as possible.\n\n"
|
|
|
+ "@ingroup Assets\n"
|
|
|
+);
|
|
|
+
|
|
|
+IMPLEMENT_CONOBJECT(AssetImportConfig);
|
|
|
+
|
|
|
+AssetImportConfig::AssetImportConfig() :
|
|
|
+ DuplicatAutoResolution("AutoRename"),
|
|
|
+ WarningsAsErrors(false),
|
|
|
+ PreventImportWithErrors(true),
|
|
|
+ AutomaticallyPromptMissingFiles(false),
|
|
|
+ ImportMesh(true),
|
|
|
+ DoUpAxisOverride(false),
|
|
|
+ UpAxisOverride("Z_AXIS"),
|
|
|
+ DoScaleOverride(false),
|
|
|
+ ScaleOverride(false),
|
|
|
+ IgnoreNodeScale(false),
|
|
|
+ AdjustCenter(false),
|
|
|
+ AdjustFloor(false),
|
|
|
+ CollapseSubmeshes(false),
|
|
|
+ LODType("TrailingNumber"),
|
|
|
+ ImportedNodes(""),
|
|
|
+ IgnoreNodes(""),
|
|
|
+ ImportMeshes(""),
|
|
|
+ IgnoreMeshes(""),
|
|
|
+ convertLeftHanded(false),
|
|
|
+ calcTangentSpace(false),
|
|
|
+ removeRedundantMats(false),
|
|
|
+ genUVCoords(false),
|
|
|
+ TransformUVs(false),
|
|
|
+ flipUVCoords(false),
|
|
|
+ findInstances(false),
|
|
|
+ limitBoneWeights(false),
|
|
|
+ JoinIdenticalVerts(false),
|
|
|
+ reverseWindingOrder(false),
|
|
|
+ invertNormals(false),
|
|
|
+ ImportMaterials(true),
|
|
|
+ CreatePBRConfig(true),
|
|
|
+ UseDiffuseSuffixOnOriginImage(false),
|
|
|
+ UseExistingMaterials(false),
|
|
|
+ IgnoreMaterials(""),
|
|
|
+ PopulateMaterialMaps(false),
|
|
|
+ ImportAnimations(true),
|
|
|
+ SeparateAnimations(false),
|
|
|
+ SeparateAnimationPrefix(""),
|
|
|
+ animTiming("FrameCount"),
|
|
|
+ animFPS(false),
|
|
|
+ GenerateCollisions(false),
|
|
|
+ GenCollisionType(""),
|
|
|
+ CollisionMeshPrefix(""),
|
|
|
+ GenerateLOSCollisions(false),
|
|
|
+ GenLOSCollisionType(""),
|
|
|
+ LOSCollisionMeshPrefix(""),
|
|
|
+ importImages(true),
|
|
|
+ ImageType("GUI"),
|
|
|
+ DiffuseTypeSuffixes("_ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL,_A,_C,-ALBEDO,-DIFFUSE,-ALB,-DIF,-COLOR,-COL,-A,-C"),
|
|
|
+ NormalTypeSuffixes("_NORMAL,_NORM,_N,-NORMAL,-NORM,-N"),
|
|
|
+ MetalnessTypeSuffixes("_METAL,_MET,_METALNESS,_METALLIC,_M,-METAL, -MET, -METALNESS, -METALLIC, -M"),
|
|
|
+ RoughnessTypeSuffixes("_ROUGH,_ROUGHNESS,_R,-ROUGH,-ROUGHNESS,-R"),
|
|
|
+ SmoothnessTypeSuffixes("_SMOOTH,_SMOOTHNESS,_S,-SMOOTH,-SMOOTHNESS,-S"),
|
|
|
+ AOTypeSuffixes("_AO,_AMBIENT,_AMBIENTOCCLUSION,-AO,-AMBIENT,-AMBIENTOCCLUSION"),
|
|
|
+ PBRTypeSuffixes("_COMP,_COMPOSITE,_PBR,-COMP,-COMPOSITE,-PBR"),
|
|
|
+ TextureFilteringMode("Bilinear"),
|
|
|
+ UseMips(true),
|
|
|
+ IsHDR(false),
|
|
|
+ Scaling(false),
|
|
|
+ ImagesCompressed(false),
|
|
|
+ GenerateMaterialOnImport(true),
|
|
|
+ importSounds(true),
|
|
|
+ VolumeAdjust(false),
|
|
|
+ PitchAdjust(false),
|
|
|
+ SoundsCompressed(false)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+AssetImportConfig::~AssetImportConfig()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/// Engine.
|
|
|
+void AssetImportConfig::initPersistFields()
|
|
|
+{
|
|
|
+ Parent::initPersistFields();
|
|
|
+
|
|
|
+ addGroup("General");
|
|
|
+ addField("DuplicatAutoResolution", TypeString, Offset(DuplicatAutoResolution, AssetImportConfig), "Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename");
|
|
|
+ addField("WarningsAsErrors", TypeBool, Offset(WarningsAsErrors, AssetImportConfig), "Indicates if warnings should be treated as errors");
|
|
|
+ addField("PreventImportWithErrors", TypeBool, Offset(PreventImportWithErrors, AssetImportConfig), "Indicates if importing should be prevented from completing if any errors are detected at all");
|
|
|
+ addField("AutomaticallyPromptMissingFiles", TypeBool, Offset(AutomaticallyPromptMissingFiles, AssetImportConfig), "Should the importer automatically prompt to find missing files if they are not detected automatically by the importer");
|
|
|
+ endGroup("General");
|
|
|
+
|
|
|
+ addGroup("Meshes");
|
|
|
+ addField("ImportMesh", TypeBool, Offset(ImportMesh, AssetImportConfig), "Indicates if this config supports importing meshes");
|
|
|
+ addField("DoUpAxisOverride", TypeBool, Offset(DoUpAxisOverride, AssetImportConfig), "Indicates if the up axis in the model file should be overridden ");
|
|
|
+ addField("UpAxisOverride", TypeString, Offset(UpAxisOverride, AssetImportConfig), "If overriding, what axis should be used as up. Options are X_AXIS, Y_AXIS, Z_AXIS");
|
|
|
+ addField("DoScaleOverride", TypeBool, Offset(DoScaleOverride, AssetImportConfig), "Indicates if the scale in the model file should be overridden");
|
|
|
+ addField("ScaleOverride", TypeF32, Offset(ScaleOverride, AssetImportConfig), "If overriding, what scale should be used");
|
|
|
+ addField("IgnoreNodeScale", TypeBool, Offset(IgnoreNodeScale, AssetImportConfig), "Indicates if scale of nodes should be ignored");
|
|
|
+ addField("AdjustCenter", TypeBool, Offset(AdjustCenter, AssetImportConfig), "Indicates if the center of the model file should be automatically recentered");
|
|
|
+ addField("AdjustFloor", TypeBool, Offset(AdjustFloor, AssetImportConfig), "Indicates if the floor height of the model file should be automatically zero'd");
|
|
|
+ addField("CollapseSubmeshes", TypeBool, Offset(CollapseSubmeshes, AssetImportConfig), "Indicates if submeshes should be collapsed down into a single main mesh");
|
|
|
+ addField("LODType", TypeString, Offset(LODType, AssetImportConfig), "Indicates what LOD mode the model file should utilize to process out LODs. Options are TrailingNumber, DetectDTS, SingleSize");
|
|
|
+ addField("ImportedNodes", TypeString, Offset(ImportedNodes, AssetImportConfig), " A list of what nodes should be guaranteed to be imported if found in the model file. Separated by either , or ;");
|
|
|
+ addField("IgnoreNodes", TypeString, Offset(IgnoreNodes, AssetImportConfig), "A list of what nodes should be guaranteed to not be imported if found in the model file. Separated by either , or ;");
|
|
|
+ addField("ImportMeshes", TypeString, Offset(ImportMeshes, AssetImportConfig), "A list of what mesh objects should be guaranteed to be imported if found in the model file. Separated by either , or ;");
|
|
|
+ addField("IgnoreMeshes", TypeString, Offset(IgnoreMeshes, AssetImportConfig), "A list of what mesh objects should be guaranteed to not be imported if found in the model file. Separated by either , or ;");
|
|
|
+ addField("convertLeftHanded", TypeBool, Offset(convertLeftHanded, AssetImportConfig), "Flag to indicate the shape loader should convert to a left-handed coordinate system");
|
|
|
+ addField("calcTangentSpace", TypeBool, Offset(calcTangentSpace, AssetImportConfig), "Should the shape loader calculate tangent space values");
|
|
|
+ addField("removeRedundantMats", TypeBool, Offset(removeRedundantMats, AssetImportConfig), "Should the shape loader automatically prune redundant/duplicate materials");
|
|
|
+ addField("genUVCoords", TypeBool, Offset(genUVCoords, AssetImportConfig), "Should the shape loader auto-generate UV Coordinates for the mesh.");
|
|
|
+ addField("TransformUVs", TypeBool, Offset(TransformUVs, AssetImportConfig), "Should the UV coordinates be transformed");
|
|
|
+ addField("flipUVCoords", TypeBool, Offset(flipUVCoords, AssetImportConfig), "Should the UV coordinates be flipped");
|
|
|
+ addField("findInstances", TypeBool, Offset(findInstances, AssetImportConfig), "Should the shape loader automatically look for instanced submeshes in the model file");
|
|
|
+ addField("limitBoneWeights", TypeBool, Offset(limitBoneWeights, AssetImportConfig), "Should the shape loader limit the bone weights");
|
|
|
+ addField("JoinIdenticalVerts", TypeBool, Offset(JoinIdenticalVerts, AssetImportConfig), "Should the shape loader automatically merge identical/duplicate verts");
|
|
|
+ addField("reverseWindingOrder", TypeBool, Offset(reverseWindingOrder, AssetImportConfig), "Should the shape loader reverse the winding order of the mesh's face indicies");
|
|
|
+ addField("invertNormals", TypeBool, Offset(invertNormals, AssetImportConfig), "Should the normals on the model be inverted");
|
|
|
+ endGroup("Meshes");
|
|
|
+
|
|
|
+ addGroup("Materials");
|
|
|
+ addField("DuplicatAutoResolution", TypeString, Offset(DuplicatAutoResolution, AssetImportConfig), "Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename");
|
|
|
+ addField("ImportMaterials", TypeBool, Offset(ImportMaterials, AssetImportConfig), "Does this config allow for importing of materials");
|
|
|
+ addField("CreatePBRConfig", TypeBool, Offset(PreventImportWithErrors, AssetImportConfig), "When importing a material, should it automatically attempt to merge Roughness, AO and Metalness maps into a single, composited PBR Configuration map");
|
|
|
+ addField("UseDiffuseSuffixOnOriginImage", TypeBool, Offset(UseDiffuseSuffixOnOriginImage, AssetImportConfig), "When generating a material off of an importing image, should the importer force appending a diffusemap suffix onto the end to avoid potential naming confusion.\n e.g. MyCoolStuff.png is imported, generating MyCoolStuff material asset and MyCoolStuff_Diffuse image asset");
|
|
|
+ addField("UseExistingMaterials", TypeBool, Offset(UseExistingMaterials, AssetImportConfig), "Should the importer try and use existing material assets in the game directory if at all possible. (Not currently utilized)");
|
|
|
+ addField("IgnoreMaterials", TypeString, Offset(IgnoreMaterials, AssetImportConfig), "A list of material names that should not be imported. Separated by either , or ;");
|
|
|
+ addField("PopulateMaterialMaps", TypeBool, Offset(PopulateMaterialMaps, AssetImportConfig), "When processing a material asset, should the importer attempt to populate the various material maps on it by looking up common naming conventions for potentially relevent image files.\n e.g. If MyCoolStuff_Diffuse.png is imported, generating MyCoolStuff material, it would also find MyCoolStuff_Normal and MyCoolStuff_PBR images and map them to the normal and PBRConfig maps respectively automatically");
|
|
|
+ endGroup("Materials");
|
|
|
+
|
|
|
+ addGroup("Meshes");
|
|
|
+ addField("ImportAnimations", TypeBool, Offset(ImportAnimations, AssetImportConfig), "Does this config allow for importing Shape Animations");
|
|
|
+ addField("SeparateAnimations", TypeBool, Offset(SeparateAnimations, AssetImportConfig), "When importing a shape file, should the animations within be separated out into unique files");
|
|
|
+ addField("SeparateAnimationPrefix", TypeString, Offset(SeparateAnimationPrefix, AssetImportConfig), "If separating animations out from a source file, what prefix should be added to the names for grouping association");
|
|
|
+ addField("animTiming", TypeString, Offset(animTiming, AssetImportConfig), "Defines the animation timing for the given animation sequence. Options are FrameTime, Seconds, Milliseconds");
|
|
|
+ addField("animFPS", TypeBool, Offset(animFPS, AssetImportConfig), "The FPS of the animation sequence");
|
|
|
+ endGroup("General");
|
|
|
+
|
|
|
+ addGroup("Collision");
|
|
|
+ addField("GenerateCollisions", TypeBool, Offset(GenerateCollisions, AssetImportConfig), "Does this configuration generate collision geometry when importing. (Not currently enabled)");
|
|
|
+ addField("GenCollisionType", TypeString, Offset(GenCollisionType, AssetImportConfig), "What sort of collision geometry is generated. (Not currently enabled)");
|
|
|
+ addField("CollisionMeshPrefix", TypeString, Offset(CollisionMeshPrefix, AssetImportConfig), "What prefix is added to the collision geometry generated. (Not currently enabled)");
|
|
|
+ addField("GenerateLOSCollisions", TypeBool, Offset(GenerateLOSCollisions, AssetImportConfig), "Does this configuration generate Line of Sight collision geometry. (Not currently enabled)");
|
|
|
+ addField("GenLOSCollisionType", TypeString, Offset(GenLOSCollisionType, AssetImportConfig), "What sort of Line of Sight collision geometry is generated. (Not currently enabled)");
|
|
|
+ addField("LOSCollisionMeshPrefix", TypeString, Offset(LOSCollisionMeshPrefix, AssetImportConfig), "What prefix is added to the Line of Sight collision geometry generated. (Not currently enabled)");
|
|
|
+ endGroup("Collision");
|
|
|
+
|
|
|
+ addGroup("Images");
|
|
|
+ addField("importImages", TypeBool, Offset(importImages, AssetImportConfig), "Does this configuration support importing images.");
|
|
|
+ addField("ImageType", TypeString, Offset(ImageType, AssetImportConfig), "What is the default ImageType images are imported as. Options are: N/A, Diffuse, Normal, Metalness, Roughness, AO, PBRConfig, GUI, Cubemap");
|
|
|
+ addField("DiffuseTypeSuffixes", TypeString, Offset(DiffuseTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a diffuse map. \n e.g. _Albedo or _Color");
|
|
|
+ addField("NormalTypeSuffixes", TypeString, Offset(NormalTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a normal map. \n e.g. _Normal or _Norm");
|
|
|
+ addField("MetalnessTypeSuffixes", TypeString, Offset(MetalnessTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a metalness map. \n e.g. _Metalness or _Metal");
|
|
|
+ addField("RoughnessTypeSuffixes", TypeString, Offset(RoughnessTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a roughness map.\n e.g. _roughness or _rough");
|
|
|
+ addField("SmoothnessTypeSuffixes", TypeString, Offset(SmoothnessTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a smoothness map. \n e.g. _smoothness or _smooth");
|
|
|
+ addField("AOTypeSuffixes", TypeString, Offset(AOTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a ambient occlusion map. \n e.g. _ambient or _ao");
|
|
|
+ addField("PBRTypeSuffixes", TypeString, Offset(PBRTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a PBRConfig map.\n e.g. _Composite or _PBR");
|
|
|
+ addField("TextureFilteringMode", TypeString, Offset(TextureFilteringMode, AssetImportConfig), "Indicates what filter mode images imported with this configuration utilizes. Options are Linear, Bilinear, Trilinear");
|
|
|
+ addField("UseMips", TypeBool, Offset(UseMips, AssetImportConfig), "Indicates if images imported with this configuration utilize mipmaps");
|
|
|
+
|
|
|
+ addField("IsHDR", TypeBool, Offset(IsHDR, AssetImportConfig), "Indicates if images imported with this configuration are in an HDR format");
|
|
|
+ addField("Scaling", TypeF32, Offset(Scaling, AssetImportConfig), "Indicates what amount of scaling images imported with this configuration use");
|
|
|
+ addField("ImagesCompressed", TypeBool, Offset(ImagesCompressed, AssetImportConfig), "Indicates if images imported with this configuration are compressed");
|
|
|
+ addField("GenerateMaterialOnImport", TypeBool, Offset(GenerateMaterialOnImport, AssetImportConfig), "Indicates if images imported with this configuration generate a parent material for it as well");
|
|
|
+ endGroup("Images");
|
|
|
+
|
|
|
+ addGroup("Sounds");
|
|
|
+ addField("importSounds", TypeBool, Offset(importSounds, AssetImportConfig), "Indicates if sounds are imported with this configuration");
|
|
|
+ addField("VolumeAdjust", TypeF32, Offset(VolumeAdjust, AssetImportConfig), "Indicates what amount the volume is adjusted on sounds imported with this configuration");
|
|
|
+ addField("PitchAdjust", TypeF32, Offset(PitchAdjust, AssetImportConfig), "Indicates what amount the pitch is adjusted on sounds imported with this configuration");
|
|
|
+ addField("SoundsCompressed", TypeBool, Offset(SoundsCompressed, AssetImportConfig), "Indicates if sounds imported with this configuration are compressed");
|
|
|
+ endGroup("Sounds");
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImportConfig::loadImportConfig(Settings* configSettings, String configName)
|
|
|
+{
|
|
|
+ //General
|
|
|
+ DuplicatAutoResolution = configSettings->value(String(configName + "/General/DuplicatAutoResolution").c_str());
|
|
|
+ WarningsAsErrors = dAtob(configSettings->value(String(configName + "/General/WarningsAsErrors").c_str()));
|
|
|
+ PreventImportWithErrors = dAtob(configSettings->value(String(configName + "/General/PreventImportWithErrors").c_str()));
|
|
|
+ AutomaticallyPromptMissingFiles = dAtob(configSettings->value(String(configName + "/General/AutomaticallyPromptMissingFiles").c_str()));
|
|
|
+
|
|
|
+ //Meshes
|
|
|
+ ImportMesh = dAtob(configSettings->value(String(configName + "/Meshes/ImportMesh").c_str()));
|
|
|
+ DoUpAxisOverride = dAtob(configSettings->value(String(configName + "/Meshes/DoUpAxisOverride").c_str()));
|
|
|
+ UpAxisOverride = configSettings->value(String(configName + "/Meshes/UpAxisOverride").c_str());
|
|
|
+ DoScaleOverride = dAtob(configSettings->value(String(configName + "/Meshes/DoScaleOverride").c_str()));
|
|
|
+ ScaleOverride = dAtof(configSettings->value(String(configName + "/Meshes/ScaleOverride").c_str()));
|
|
|
+ IgnoreNodeScale = dAtob(configSettings->value(String(configName + "/Meshes/IgnoreNodeScale").c_str()));
|
|
|
+ AdjustCenter = dAtob(configSettings->value(String(configName + "/Meshes/AdjustCenter").c_str()));
|
|
|
+ AdjustFloor = dAtob(configSettings->value(String(configName + "/Meshes/AdjustFloor").c_str()));
|
|
|
+ CollapseSubmeshes = dAtob(configSettings->value(String(configName + "/Meshes/CollapseSubmeshes").c_str()));
|
|
|
+ LODType = configSettings->value(String(configName + "/Meshes/LODType").c_str());
|
|
|
+ ImportedNodes = configSettings->value(String(configName + "/Meshes/ImportedNodes").c_str());
|
|
|
+ IgnoreNodes = configSettings->value(String(configName + "/Meshes/IgnoreNodes").c_str());
|
|
|
+ ImportMeshes = configSettings->value(String(configName + "/Meshes/ImportMeshes").c_str());
|
|
|
+ IgnoreMeshes = configSettings->value(String(configName + "/Meshes/IgnoreMeshes").c_str());
|
|
|
+
|
|
|
+ //Assimp/Collada
|
|
|
+ convertLeftHanded = dAtob(configSettings->value(String(configName + "/Meshes/convertLeftHanded").c_str()));
|
|
|
+ calcTangentSpace = dAtob(configSettings->value(String(configName + "/Meshes/calcTangentSpace").c_str()));
|
|
|
+ removeRedundantMats = dAtob(configSettings->value(String(configName + "/Meshes/removeRedundantMats").c_str()));
|
|
|
+ genUVCoords = dAtob(configSettings->value(String(configName + "/Meshes/genUVCoords").c_str()));
|
|
|
+ TransformUVs = dAtob(configSettings->value(String(configName + "/Meshes/TransformUVs").c_str()));
|
|
|
+ flipUVCoords = dAtob(configSettings->value(String(configName + "/Meshes/flipUVCoords").c_str()));
|
|
|
+ findInstances = dAtob(configSettings->value(String(configName + "/Meshes/findInstances").c_str()));
|
|
|
+ limitBoneWeights = dAtob(configSettings->value(String(configName + "/Meshes/limitBoneWeights").c_str()));
|
|
|
+ JoinIdenticalVerts = dAtob(configSettings->value(String(configName + "/Meshes/JoinIdenticalVerts").c_str()));
|
|
|
+ reverseWindingOrder = dAtob(configSettings->value(String(configName + "/Meshes/reverseWindingOrder").c_str()));
|
|
|
+ invertNormals = dAtob(configSettings->value(String(configName + "/Meshes/invertNormals").c_str()));
|
|
|
+
|
|
|
+ //Materials
|
|
|
+ ImportMaterials = dAtob(configSettings->value(String(configName + "/Materials/ImportMaterials").c_str()));
|
|
|
+ CreatePBRConfig = dAtob(configSettings->value(String(configName + "/Materials/CreatePBRConfig").c_str()));
|
|
|
+ UseDiffuseSuffixOnOriginImage = dAtob(configSettings->value(String(configName + "/Materials/UseDiffuseSuffixOnOriginImage").c_str()));
|
|
|
+ UseExistingMaterials = dAtob(configSettings->value(String(configName + "/Materials/UseExistingMaterials").c_str()));
|
|
|
+ IgnoreMaterials = configSettings->value(String(configName + "/Materials/IgnoreMaterials").c_str());
|
|
|
+ PopulateMaterialMaps = dAtob(configSettings->value(String(configName + "/Materials/invertPopulateMaterialMapsNormals").c_str()));
|
|
|
+
|
|
|
+ //Animations
|
|
|
+ ImportAnimations = dAtob(configSettings->value(String(configName + "/Animations/ImportAnimations").c_str()));
|
|
|
+ SeparateAnimations = dAtob(configSettings->value(String(configName + "/Animations/SeparateAnimations").c_str()));
|
|
|
+ SeparateAnimationPrefix = configSettings->value(String(configName + "/Animations/SeparateAnimationPrefix").c_str());
|
|
|
+ animTiming = configSettings->value(String(configName + "/Animations/animTiming").c_str());
|
|
|
+ animFPS = dAtof(configSettings->value(String(configName + "/Animations/animFPS").c_str()));
|
|
|
+
|
|
|
+ //Collisions
|
|
|
+ GenerateCollisions = dAtob(configSettings->value(String(configName + "/Collision/GenerateCollisions").c_str()));
|
|
|
+ GenCollisionType = configSettings->value(String(configName + "/Collision/GenCollisionType").c_str());
|
|
|
+ CollisionMeshPrefix = configSettings->value(String(configName + "/Collision/CollisionMeshPrefix").c_str());
|
|
|
+ GenerateLOSCollisions = dAtob(configSettings->value(String(configName + "/Collision/GenerateLOSCollisions").c_str()));
|
|
|
+ GenLOSCollisionType = configSettings->value(String(configName + "/Collision/GenLOSCollisionType").c_str());
|
|
|
+ LOSCollisionMeshPrefix = configSettings->value(String(configName + "/Collision/LOSCollisionMeshPrefix").c_str());
|
|
|
+
|
|
|
+ //Images
|
|
|
+ importImages = dAtob(configSettings->value(String(configName + "/Images/importImages").c_str()));
|
|
|
+ ImageType = configSettings->value(String(configName + "/Images/ImageType").c_str());
|
|
|
+ DiffuseTypeSuffixes = configSettings->value(String(configName + "/Images/DiffuseTypeSuffixes").c_str());
|
|
|
+ NormalTypeSuffixes = configSettings->value(String(configName + "/Images/NormalTypeSuffixes").c_str());
|
|
|
+ MetalnessTypeSuffixes = configSettings->value(String(configName + "/Images/MetalnessTypeSuffixes").c_str());
|
|
|
+ RoughnessTypeSuffixes = configSettings->value(String(configName + "/Images/RoughnessTypeSuffixes").c_str());
|
|
|
+ SmoothnessTypeSuffixes = configSettings->value(String(configName + "/Images/SmoothnessTypeSuffixes").c_str());
|
|
|
+ AOTypeSuffixes = configSettings->value(String(configName + "/Images/AOTypeSuffixes").c_str());
|
|
|
+ PBRTypeSuffixes = configSettings->value(String(configName + "/Images/PBRTypeSuffixes").c_str());
|
|
|
+ TextureFilteringMode = configSettings->value(String(configName + "/Images/TextureFilteringMode").c_str());
|
|
|
+ UseMips = dAtob(configSettings->value(String(configName + "/Images/UseMips").c_str()));
|
|
|
+ IsHDR = dAtob(configSettings->value(String(configName + "/Images/IsHDR").c_str()));
|
|
|
+ Scaling = dAtof(configSettings->value(String(configName + "/Images/Scaling").c_str()));
|
|
|
+ ImagesCompressed = dAtob(configSettings->value(String(configName + "/Images/Compressed").c_str()));
|
|
|
+ GenerateMaterialOnImport = dAtob(configSettings->value(String(configName + "/Images/GenerateMaterialOnImport").c_str()));
|
|
|
+
|
|
|
+ //Sounds
|
|
|
+ VolumeAdjust = dAtof(configSettings->value(String(configName + "/Sounds/VolumeAdjust").c_str()));
|
|
|
+ PitchAdjust = dAtof(configSettings->value(String(configName + "/Sounds/PitchAdjust").c_str()));
|
|
|
+ SoundsCompressed = dAtob(configSettings->value(String(configName + "/Sounds/Compressed").c_str()));
|
|
|
+}
|
|
|
+
|
|
|
+ConsoleDocClass(AssetImportObject,
|
|
|
+ "@brief Defines properties for an AssetImportObject object.\n"
|
|
|
+ "@AssetImportObject is a SimObject derived object intended to act as a stand-in for the to-be imported objects.\n"
|
|
|
+ "@It contains important info such as dependencies, if it's been processed, any error/status issues and the originating file\n"
|
|
|
+ "@or if it's been programmatically generated as part of the import process.\n\n"
|
|
|
+ "@ingroup Assets\n"
|
|
|
+);
|
|
|
+
|
|
|
+IMPLEMENT_CONOBJECT(AssetImportObject);
|
|
|
+
|
|
|
+AssetImportObject::AssetImportObject() :
|
|
|
+ dirty(false),
|
|
|
+ skip(false),
|
|
|
+ processed(false),
|
|
|
+ generatedAsset(false),
|
|
|
+ parentAssetItem(nullptr),
|
|
|
+ tamlFilePath(""),
|
|
|
+ imageSuffixType(""),
|
|
|
+ shapeInfo(nullptr)
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+AssetImportObject::~AssetImportObject()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImportObject::initPersistFields()
|
|
|
+{
|
|
|
+ Parent::initPersistFields();
|
|
|
+
|
|
|
+ addField("assetType", TypeString, Offset(assetType, AssetImportObject), "What type is the importing asset");
|
|
|
+ addField("filePath", TypeFilename, Offset(filePath, AssetImportObject), "What is the source file path of the importing asset");
|
|
|
+ addField("assetName", TypeString, Offset(assetName, AssetImportObject), "What is the asset's name");
|
|
|
+ addField("cleanAssetName", TypeString, Offset(cleanAssetName, AssetImportObject), "What is the original, unmodified by processing, asset name");
|
|
|
+ addField("status", TypeString, Offset(status, AssetImportObject), "What is the current status of this asset item in it's import process");
|
|
|
+ addField("statusType", TypeString, Offset(statusType, AssetImportObject), "If there is a warning or error status, what type is the condition for this asset item");
|
|
|
+ addField("statusInfo", TypeString, Offset(statusInfo, AssetImportObject), "What is the articulated information of the status of the asset. Contains the error or warning log data");
|
|
|
+
|
|
|
+ addField("dirty", TypeBool, Offset(dirty, AssetImportObject), "Is the asset item currently flagged as dirty");
|
|
|
+ addField("skip", TypeBool, Offset(skip, AssetImportObject), "Is this asset item marked to be skipped. If it is, it's usually due to being marked as deleted");
|
|
|
+ addField("processed", TypeBool, Offset(processed, AssetImportObject), "Has the asset item been processed");
|
|
|
+ addField("generatedAsset", TypeBool, Offset(generatedAsset, AssetImportObject), "Is this specific asset item generated as part of the import process of another item");
|
|
|
+
|
|
|
+ addField("tamlFilePath", TypeString, Offset(tamlFilePath, AssetImportObject), "What is the ultimate asset taml file path for this import item");
|
|
|
+
|
|
|
+ addField("imageSuffixType", TypeString, Offset(imageSuffixType, AssetImportObject), "Specific to ImageAsset type. What is the image asset's suffix type. Options are: Albedo, Normal, Roughness, AO, Metalness, PBRConfig");
|
|
|
+
|
|
|
+ addField("shapeInfo", TYPEID< GuiTreeViewCtrl >(), Offset(shapeInfo, AssetImportObject), "Specific to ShapeAsset type. Processed information about the shape file. Contains numbers and lists of meshes, materials and animations");
|
|
|
+}
|
|
|
+
|
|
|
+ConsoleDocClass(AssetImporter,
|
|
|
+ "@brief Defines properties for an AssetImportObject object.\n"
|
|
|
+ "@AssetImportObject is a SimObject derived object intended to act as a stand-in for the to-be imported objects.\n"
|
|
|
+ "@It contains important info such as dependencies, if it's been processed, any error/status issues and the originating file\n"
|
|
|
+ "@or if it's been programmatically generated as part of the import process.\n\n"
|
|
|
+ "@ingroup Assets\n"
|
|
|
+);
|
|
|
+
|
|
|
+IMPLEMENT_CONOBJECT(AssetImporter);
|
|
|
+
|
|
|
+AssetImporter::AssetImporter() :
|
|
|
+ importIssues(false),
|
|
|
+ isReimport(false),
|
|
|
+ assetHeirarchyChanged(false),
|
|
|
+ importLogBuffer("")
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+AssetImporter::~AssetImporter()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::initPersistFields()
|
|
|
+{
|
|
|
+ Parent::initPersistFields();
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// Utility Functions
|
|
|
+//
|
|
|
+
|
|
|
+AssetImportObject* AssetImporter::addImportingFile(Torque::Path filePath)
|
|
|
+{
|
|
|
+ String assetType = getAssetTypeByFile(filePath);
|
|
|
+
|
|
|
+ if (assetType.isEmpty())
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is of an unrecognized/unsupported type.", filePath.getFullPath().c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ AssetImportObject* newAssetItem = addImportingAsset(assetType, filePath, nullptr, "");
|
|
|
+
|
|
|
+ originalImportingFiles.push_back(filePath);
|
|
|
+
|
|
|
+ return newAssetItem;
|
|
|
+}
|
|
|
+
|
|
|
+AssetImportObject* AssetImporter::addImportingAsset(String assetType, Torque::Path filePath, AssetImportObject* parentItem, String assetNameOverride)
|
|
|
+{
|
|
|
+ String assetName;
|
|
|
+
|
|
|
+ //In some cases(usually generated assets on import, like materials) we'll want to specifically define the asset name instead of peeled from the filePath
|
|
|
+ if (assetNameOverride.isNotEmpty())
|
|
|
+ assetName = assetNameOverride;
|
|
|
+ else
|
|
|
+ assetName = filePath.getFileName();
|
|
|
+
|
|
|
+ AssetImportObject* assetImportObj = new AssetImportObject();
|
|
|
+ assetImportObj->registerObject();
|
|
|
+
|
|
|
+ assetImportObj->assetType = assetType;
|
|
|
+ assetImportObj->filePath = filePath;
|
|
|
+ assetImportObj->assetName = assetName;
|
|
|
+ assetImportObj->cleanAssetName = assetName;
|
|
|
+ assetImportObj->moduleName = targetModuleId;
|
|
|
+ assetImportObj->status = "";
|
|
|
+ assetImportObj->statusType = "";
|
|
|
+ assetImportObj->statusInfo = "";
|
|
|
+
|
|
|
+ assetImportObj->dirty = false;
|
|
|
+ assetImportObj->skip = false;
|
|
|
+ assetImportObj->processed = false;
|
|
|
+ assetImportObj->generatedAsset = false;
|
|
|
+
|
|
|
+ if (parentItem != nullptr)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Added Child Importing Asset to %s", parentItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ parentItem->childAssetItems.push_back(assetImportObj);
|
|
|
+ assetImportObj->parentAssetItem = parentItem;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Added Importing Asset");
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), " Asset Info: Name: %s | Type: %s", assetImportObj->assetName.c_str(), assetImportObj->assetType.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ if (!filePath.isEmpty())
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), " File: %s", filePath.getFullPath().c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ return assetImportObj;
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::deleteImportingAsset(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ assetItem->skip = true;
|
|
|
+
|
|
|
+ //log it
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Deleting Importing Asset %s and all it's child items", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+}
|
|
|
+
|
|
|
+AssetImportObject* AssetImporter::findImportingAssetByName(String assetName, AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ if (assetItem == nullptr)
|
|
|
+ {
|
|
|
+ for (U32 i = 0; i < importingAssets.size(); i++)
|
|
|
+ {
|
|
|
+ if (importingAssets[i]->cleanAssetName == assetName)
|
|
|
+ {
|
|
|
+ return importingAssets[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ //If it wasn't a match, try recusing on the children(if any)
|
|
|
+ AssetImportObject* retItem = findImportingAssetByName(assetName, importingAssets[i]);
|
|
|
+ if (retItem != nullptr)
|
|
|
+ return retItem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //this is the child recursing section
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ if (assetItem->childAssetItems[i]->cleanAssetName == assetName)
|
|
|
+ {
|
|
|
+ return assetItem->childAssetItems[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ //If it wasn't a match, try recusing on the children(if any)
|
|
|
+ AssetImportObject* retItem = findImportingAssetByName(assetName, assetItem->childAssetItems[i]);
|
|
|
+ if (retItem != nullptr)
|
|
|
+ return retItem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nullptr;
|
|
|
+}
|
|
|
+
|
|
|
+ModuleDefinition* AssetImporter::getModuleFromPath(Torque::Path filePath)
|
|
|
+{
|
|
|
+ U32 folderCount = StringUnit::getUnitCount(filePath.getPath().c_str(), "/");
|
|
|
+
|
|
|
+ for (U32 i = 0; i < folderCount; i++)
|
|
|
+ {
|
|
|
+ String folderName = StringUnit::getUnit(filePath.getPath().c_str(), i, "/");
|
|
|
+
|
|
|
+ ModuleDefinition* moduleDef = ModuleDatabase.findModule(folderName.c_str(), 1);
|
|
|
+ if (moduleDef != nullptr)
|
|
|
+ return moduleDef;
|
|
|
+ }
|
|
|
+
|
|
|
+ return nullptr;
|
|
|
+}
|
|
|
+
|
|
|
+String AssetImporter::parseImageSuffixes(String assetName, String* suffixType)
|
|
|
+{
|
|
|
+ //Here, we loop over our different suffix lists progressively.
|
|
|
+ //This lets us walk through a list of suffixes in the Import Config, such as DiffuseTypeSuffixes
|
|
|
+ //And then iterate over the delinated list of items within it to look for a match.
|
|
|
+ //If we don't find a match, we then increment our list switch index and scan through the next list.
|
|
|
+ U32 suffixTypeIdx = 0;
|
|
|
+ while (suffixTypeIdx < 6)
|
|
|
+ {
|
|
|
+ String suffixList;
|
|
|
+ switch (suffixTypeIdx)
|
|
|
+ {
|
|
|
+ case 0:
|
|
|
+ suffixList = activeImportConfig.DiffuseTypeSuffixes;
|
|
|
+ suffixType->insert(0, "Albedo", 10);
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ suffixList = activeImportConfig.NormalTypeSuffixes;
|
|
|
+ suffixType->insert(0, "Normal", 10);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ suffixList = activeImportConfig.RoughnessTypeSuffixes;
|
|
|
+ suffixType->insert(0, "Roughness", 10);
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ suffixList = activeImportConfig.AOTypeSuffixes;
|
|
|
+ suffixType->insert(0, "AO", 10);
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ suffixList = activeImportConfig.MetalnessTypeSuffixes;
|
|
|
+ suffixType->insert(0, "Metalness", 10);
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ suffixList = activeImportConfig.PBRTypeSuffixes;
|
|
|
+ suffixType->insert(0, "PBRConfig", 10);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ suffixList = "";
|
|
|
+ }
|
|
|
+
|
|
|
+ suffixTypeIdx++;
|
|
|
+
|
|
|
+ U32 suffixCount = StringUnit::getUnitCount(suffixList, ",;");
|
|
|
+ for (U32 i = 0; i < suffixCount; i++)
|
|
|
+ {
|
|
|
+ String suffix = StringUnit::getUnit(suffixList, i, ",;");
|
|
|
+ String searchSuffix = String("*") + suffix;
|
|
|
+ if (FindMatch::isMatch(searchSuffix.c_str(), assetName.c_str(), false))
|
|
|
+ {
|
|
|
+ //We have a match, so indicate as such
|
|
|
+ return suffix;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return "";
|
|
|
+}
|
|
|
+
|
|
|
+String AssetImporter::getAssetTypeByFile(Torque::Path filePath)
|
|
|
+{
|
|
|
+ String fileExt = filePath.getExtension();
|
|
|
+
|
|
|
+ if (fileExt == String("png") || fileExt == String("jpg") || fileExt == String("jpeg") || fileExt == String("dds"))
|
|
|
+ return "ImageAsset";
|
|
|
+ else if (fileExt == String("dae") || fileExt == String("fbx") || fileExt == String("blend") || fileExt == String("obj") || fileExt == String("dts") || fileExt == String("gltf") || fileExt == String("gltb"))
|
|
|
+ return "ShapeAsset";
|
|
|
+ else if (fileExt == String("dsq"))
|
|
|
+ return "ShapeAnimationAsset";
|
|
|
+ else if (fileExt == String("ogg") || fileExt == String("wav") || fileExt == String("mp3"))
|
|
|
+ return "SoundAsset";
|
|
|
+ else if (fileExt == String("zip"))
|
|
|
+ return "Zip";
|
|
|
+ else if (fileExt.isEmpty())
|
|
|
+ return "Folder";
|
|
|
+
|
|
|
+ return "";
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::resetImportSession()
|
|
|
+{
|
|
|
+ importingAssets.clear();
|
|
|
+ activityLog.clear();
|
|
|
+
|
|
|
+ for (U32 i = 0; i < originalImportingFiles.size(); i++)
|
|
|
+ {
|
|
|
+ addImportingFile(originalImportingFiles[i]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+S32 AssetImporter::getActivityLogLineCount()
|
|
|
+{
|
|
|
+ return activityLog.size();
|
|
|
+}
|
|
|
+
|
|
|
+String AssetImporter::getActivityLogLine(U32 line)
|
|
|
+{
|
|
|
+ if (line >= activityLog.size())
|
|
|
+ return "";
|
|
|
+
|
|
|
+ return activityLog[line];
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::dumpActivityLog()
|
|
|
+{
|
|
|
+ for (U32 i = 0; i < activityLog.size(); i++)
|
|
|
+ {
|
|
|
+ Con::printf(activityLog[i].c_str());
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+S32 AssetImporter::getAssetItemCount()
|
|
|
+{
|
|
|
+ return importingAssets.size();
|
|
|
+}
|
|
|
+
|
|
|
+AssetImportObject* AssetImporter::getAssetItem(U32 index)
|
|
|
+{
|
|
|
+ if (index >= importingAssets.size())
|
|
|
+ return nullptr;
|
|
|
+
|
|
|
+ return importingAssets[index];
|
|
|
+}
|
|
|
+
|
|
|
+S32 AssetImporter::getAssetItemChildCount(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ return assetItem->childAssetItems.size();
|
|
|
+}
|
|
|
+
|
|
|
+AssetImportObject* AssetImporter::getAssetItemChild(AssetImportObject* assetItem, U32 index)
|
|
|
+{
|
|
|
+ if (index >= assetItem->childAssetItems.size())
|
|
|
+ return nullptr;
|
|
|
+
|
|
|
+ return assetItem->childAssetItems[index];
|
|
|
+}
|
|
|
+//
|
|
|
+// Processing
|
|
|
+//
|
|
|
+// Helper struct for counting nodes, meshes and polygons down through the scene
|
|
|
+// hierarchy
|
|
|
+struct SceneStats
|
|
|
+{
|
|
|
+ S32 numNodes;
|
|
|
+ S32 numMeshes;
|
|
|
+ S32 numPolygons;
|
|
|
+ S32 numMaterials;
|
|
|
+ S32 numLights;
|
|
|
+ S32 numClips;
|
|
|
+
|
|
|
+ SceneStats() : numNodes(0), numMeshes(0), numPolygons(0), numMaterials(0), numLights(0), numClips(0) { }
|
|
|
+};
|
|
|
+
|
|
|
+// Recurse through the <visual_scene> adding nodes and geometry to the GuiTreeView control
|
|
|
+static void processNode(GuiTreeViewCtrl* tree, domNode* node, S32 parentID, SceneStats& stats)
|
|
|
+{
|
|
|
+ stats.numNodes++;
|
|
|
+ S32 nodeID = tree->insertItem(parentID, _GetNameOrId(node), "node", "", 0, 0);
|
|
|
+
|
|
|
+ // Update mesh and poly counts
|
|
|
+ for (S32 i = 0; i < node->getContents().getCount(); i++)
|
|
|
+ {
|
|
|
+ domGeometry* geom = 0;
|
|
|
+ const char* elemName = "";
|
|
|
+
|
|
|
+ daeElement* child = node->getContents()[i];
|
|
|
+ switch (child->getElementType())
|
|
|
+ {
|
|
|
+ case COLLADA_TYPE::INSTANCE_GEOMETRY:
|
|
|
+ {
|
|
|
+ domInstance_geometry* instgeom = daeSafeCast<domInstance_geometry>(child);
|
|
|
+ if (instgeom)
|
|
|
+ {
|
|
|
+ geom = daeSafeCast<domGeometry>(instgeom->getUrl().getElement());
|
|
|
+ elemName = _GetNameOrId(geom);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ case COLLADA_TYPE::INSTANCE_CONTROLLER:
|
|
|
+ {
|
|
|
+ domInstance_controller* instctrl = daeSafeCast<domInstance_controller>(child);
|
|
|
+ if (instctrl)
|
|
|
+ {
|
|
|
+ domController* ctrl = daeSafeCast<domController>(instctrl->getUrl().getElement());
|
|
|
+ elemName = _GetNameOrId(ctrl);
|
|
|
+ if (ctrl && ctrl->getSkin())
|
|
|
+ geom = daeSafeCast<domGeometry>(ctrl->getSkin()->getSource().getElement());
|
|
|
+ else if (ctrl && ctrl->getMorph())
|
|
|
+ geom = daeSafeCast<domGeometry>(ctrl->getMorph()->getSource().getElement());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ case COLLADA_TYPE::INSTANCE_LIGHT:
|
|
|
+ stats.numLights++;
|
|
|
+ tree->insertItem(nodeID, _GetNameOrId(node), "light", "", 0, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (geom && geom->getMesh())
|
|
|
+ {
|
|
|
+ const char* name = _GetNameOrId(node);
|
|
|
+ if (dStrEqual(name, "null") || dStrEndsWith(name, "PIVOT"))
|
|
|
+ name = _GetNameOrId(daeSafeCast<domNode>(node->getParent()));
|
|
|
+
|
|
|
+ stats.numMeshes++;
|
|
|
+ tree->insertItem(nodeID, name, "mesh", "", 0, 0);
|
|
|
+
|
|
|
+ for (S32 j = 0; j < geom->getMesh()->getTriangles_array().getCount(); j++)
|
|
|
+ stats.numPolygons += geom->getMesh()->getTriangles_array()[j]->getCount();
|
|
|
+ for (S32 j = 0; j < geom->getMesh()->getTristrips_array().getCount(); j++)
|
|
|
+ stats.numPolygons += geom->getMesh()->getTristrips_array()[j]->getCount();
|
|
|
+ for (S32 j = 0; j < geom->getMesh()->getTrifans_array().getCount(); j++)
|
|
|
+ stats.numPolygons += geom->getMesh()->getTrifans_array()[j]->getCount();
|
|
|
+ for (S32 j = 0; j < geom->getMesh()->getPolygons_array().getCount(); j++)
|
|
|
+ stats.numPolygons += geom->getMesh()->getPolygons_array()[j]->getCount();
|
|
|
+ for (S32 j = 0; j < geom->getMesh()->getPolylist_array().getCount(); j++)
|
|
|
+ stats.numPolygons += geom->getMesh()->getPolylist_array()[j]->getCount();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Recurse into child nodes
|
|
|
+ for (S32 i = 0; i < node->getNode_array().getCount(); i++)
|
|
|
+ processNode(tree, node->getNode_array()[i], nodeID, stats);
|
|
|
+
|
|
|
+ for (S32 i = 0; i < node->getInstance_node_array().getCount(); i++)
|
|
|
+ {
|
|
|
+ domInstance_node* instnode = node->getInstance_node_array()[i];
|
|
|
+ domNode* dNode = daeSafeCast<domNode>(instnode->getUrl().getElement());
|
|
|
+ if (dNode)
|
|
|
+ processNode(tree, dNode, nodeID, stats);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static bool enumColladaForImport(const char* shapePath, GuiTreeViewCtrl* tree, bool loadCachedDts)
|
|
|
+{
|
|
|
+ // Check if a cached DTS is available => no need to import the collada file
|
|
|
+ // if we can load the DTS instead
|
|
|
+ Torque::Path path(shapePath);
|
|
|
+ if (loadCachedDts && ColladaShapeLoader::canLoadCachedDTS(path))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ // Check if this is a Sketchup file (.kmz) and if so, mount the zip filesystem
|
|
|
+ // and get the path to the DAE file.
|
|
|
+ String mountPoint;
|
|
|
+ Torque::Path daePath;
|
|
|
+ bool isSketchup = ColladaShapeLoader::checkAndMountSketchup(path, mountPoint, daePath);
|
|
|
+
|
|
|
+ // Load the Collada file into memory
|
|
|
+ domCOLLADA* root = ColladaShapeLoader::getDomCOLLADA(daePath);
|
|
|
+ if (!root)
|
|
|
+ {
|
|
|
+ TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Load complete");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isSketchup)
|
|
|
+ {
|
|
|
+ // Unmount the zip if we mounted it
|
|
|
+ Torque::FS::Unmount(mountPoint);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Initialize tree
|
|
|
+ tree->removeItem(0);
|
|
|
+ S32 nodesID = tree->insertItem(0, "Shape", "", "", 0, 0);
|
|
|
+ S32 matsID = tree->insertItem(0, "Materials", "", "", 0, 0);
|
|
|
+ S32 animsID = tree->insertItem(0, "Animations", "", "", 0, 0);
|
|
|
+
|
|
|
+ SceneStats stats;
|
|
|
+
|
|
|
+ // Query DOM for shape summary details
|
|
|
+ for (S32 i = 0; i < root->getLibrary_visual_scenes_array().getCount(); i++)
|
|
|
+ {
|
|
|
+ const domLibrary_visual_scenes* libScenes = root->getLibrary_visual_scenes_array()[i];
|
|
|
+ for (S32 j = 0; j < libScenes->getVisual_scene_array().getCount(); j++)
|
|
|
+ {
|
|
|
+ const domVisual_scene* visualScene = libScenes->getVisual_scene_array()[j];
|
|
|
+ for (S32 k = 0; k < visualScene->getNode_array().getCount(); k++)
|
|
|
+ processNode(tree, visualScene->getNode_array()[k], nodesID, stats);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get material count
|
|
|
+ for (S32 i = 0; i < root->getLibrary_materials_array().getCount(); i++)
|
|
|
+ {
|
|
|
+ const domLibrary_materials* libraryMats = root->getLibrary_materials_array()[i];
|
|
|
+ stats.numMaterials += libraryMats->getMaterial_array().getCount();
|
|
|
+ for (S32 j = 0; j < libraryMats->getMaterial_array().getCount(); j++)
|
|
|
+ {
|
|
|
+ domMaterial* mat = libraryMats->getMaterial_array()[j];
|
|
|
+ tree->insertItem(matsID, _GetNameOrId(mat), "", "", 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get images count
|
|
|
+ for (S32 i = 0; i < root->getLibrary_images_array().getCount(); i++)
|
|
|
+ {
|
|
|
+ const domLibrary_images* libraryImages = root->getLibrary_images_array()[i];
|
|
|
+
|
|
|
+ for (S32 j = 0; j < libraryImages->getImage_array().getCount(); j++)
|
|
|
+ {
|
|
|
+ domImage* img = libraryImages->getImage_array()[j];
|
|
|
+
|
|
|
+ S32 materialID = tree->findItemByName(_GetNameOrId(img));
|
|
|
+
|
|
|
+ if (materialID == 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ tree->setItemValue(materialID, img->getInit_from()->getValue().str().c_str());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get animation count
|
|
|
+ for (S32 i = 0; i < root->getLibrary_animation_clips_array().getCount(); i++)
|
|
|
+ {
|
|
|
+ const domLibrary_animation_clips* libraryClips = root->getLibrary_animation_clips_array()[i];
|
|
|
+ stats.numClips += libraryClips->getAnimation_clip_array().getCount();
|
|
|
+ for (S32 j = 0; j < libraryClips->getAnimation_clip_array().getCount(); j++)
|
|
|
+ {
|
|
|
+ domAnimation_clip* clip = libraryClips->getAnimation_clip_array()[j];
|
|
|
+ tree->insertItem(animsID, _GetNameOrId(clip), "animation", "", 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (stats.numClips == 0)
|
|
|
+ {
|
|
|
+ // No clips => check if there are any animations (these will be added to a default clip)
|
|
|
+ for (S32 i = 0; i < root->getLibrary_animations_array().getCount(); i++)
|
|
|
+ {
|
|
|
+ const domLibrary_animations* libraryAnims = root->getLibrary_animations_array()[i];
|
|
|
+ if (libraryAnims->getAnimation_array().getCount())
|
|
|
+ {
|
|
|
+ stats.numClips = 1;
|
|
|
+ tree->insertItem(animsID, "ambient", "animation", "", 0, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Extract the global scale and up_axis from the top level <asset> element,
|
|
|
+ F32 unit = 1.0f;
|
|
|
+ domUpAxisType upAxis = UPAXISTYPE_Z_UP;
|
|
|
+ if (root->getAsset()) {
|
|
|
+ if (root->getAsset()->getUnit())
|
|
|
+ unit = root->getAsset()->getUnit()->getMeter();
|
|
|
+ if (root->getAsset()->getUp_axis())
|
|
|
+ upAxis = root->getAsset()->getUp_axis()->getValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Load complete");
|
|
|
+
|
|
|
+ // Store shape information in the tree control
|
|
|
+ tree->setDataField(StringTable->insert("_nodeCount"), 0, avar("%d", stats.numNodes));
|
|
|
+ tree->setDataField(StringTable->insert("_meshCount"), 0, avar("%d", stats.numMeshes));
|
|
|
+ tree->setDataField(StringTable->insert("_polygonCount"), 0, avar("%d", stats.numPolygons));
|
|
|
+ tree->setDataField(StringTable->insert("_materialCount"), 0, avar("%d", stats.numMaterials));
|
|
|
+ tree->setDataField(StringTable->insert("_lightCount"), 0, avar("%d", stats.numLights));
|
|
|
+ tree->setDataField(StringTable->insert("_animCount"), 0, avar("%d", stats.numClips));
|
|
|
+ tree->setDataField(StringTable->insert("_unit"), 0, avar("%g", unit));
|
|
|
+
|
|
|
+ if (upAxis == UPAXISTYPE_X_UP)
|
|
|
+ tree->setDataField(StringTable->insert("_upAxis"), 0, "X_AXIS");
|
|
|
+ else if (upAxis == UPAXISTYPE_Y_UP)
|
|
|
+ tree->setDataField(StringTable->insert("_upAxis"), 0, "Y_AXIS");
|
|
|
+ else
|
|
|
+ tree->setDataField(StringTable->insert("_upAxis"), 0, "Z_AXIS");
|
|
|
+
|
|
|
+ char shapesStr[16];
|
|
|
+ dSprintf(shapesStr, 16, "%i", stats.numMeshes);
|
|
|
+ char materialsStr[16];
|
|
|
+ dSprintf(materialsStr, 16, "%i", stats.numMaterials);
|
|
|
+ char animationsStr[16];
|
|
|
+ dSprintf(animationsStr, 16, "%i", stats.numClips);
|
|
|
+
|
|
|
+ tree->setItemValue(nodesID, StringTable->insert(shapesStr));
|
|
|
+ tree->setItemValue(matsID, StringTable->insert(materialsStr));
|
|
|
+ tree->setItemValue(animsID, StringTable->insert(animationsStr));
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::processImportAssets(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ if (assetItem == nullptr)
|
|
|
+ {
|
|
|
+ assetHeirarchyChanged = false;
|
|
|
+
|
|
|
+ for (U32 i = 0; i < importingAssets.size(); i++)
|
|
|
+ {
|
|
|
+ AssetImportObject* item = importingAssets[i];
|
|
|
+ if (item->skip)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (!item->processed)
|
|
|
+ {
|
|
|
+ //Sanitize before modifying our asset name(suffix additions, etc)
|
|
|
+ if (item->assetName != item->cleanAssetName)
|
|
|
+ item->assetName = item->cleanAssetName;
|
|
|
+
|
|
|
+ //handle special pre-processing here for any types that need it
|
|
|
+
|
|
|
+ //process the asset items
|
|
|
+ if (item->assetType == String("ImageAsset"))
|
|
|
+ processImageAsset(item);
|
|
|
+ else if (item->assetType == String("ShapeAsset"))
|
|
|
+ processShapeAsset(item);
|
|
|
+ /*else if (item->assetType == String("SoundAsset"))
|
|
|
+ SoundAsset::prepareAssetForImport(this, item);*/
|
|
|
+ else if (item->assetType == String("MaterialAsset"))
|
|
|
+ processMaterialAsset(item);
|
|
|
+ /*else if (item->assetType == String("ShapeAnimationAsset"))
|
|
|
+ ShapeAnimationAsset::prepareAssetForImport(this, item);*/
|
|
|
+
|
|
|
+ item->processed = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ //try recusing on the children(if any)
|
|
|
+ processImportAssets(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //this is the child recursing section
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ AssetImportObject* childItem = assetItem->childAssetItems[i];
|
|
|
+
|
|
|
+ if (childItem->skip)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (!childItem->processed)
|
|
|
+ {
|
|
|
+ //Sanitize before modifying our asset name(suffix additions, etc)
|
|
|
+ if (childItem->assetName != childItem->cleanAssetName)
|
|
|
+ childItem->assetName = childItem->cleanAssetName;
|
|
|
+
|
|
|
+ //handle special pre-processing here for any types that need it
|
|
|
+
|
|
|
+ //process the asset items
|
|
|
+ if (childItem->assetType == String("ImageAsset"))
|
|
|
+ processImageAsset(childItem);
|
|
|
+ else if (childItem->assetType == String("ShapeAsset"))
|
|
|
+ processShapeAsset(childItem);
|
|
|
+ /*else if (childItem->assetType == String("SoundAsset"))
|
|
|
+ SoundAsset::prepareAssetForImport(this, childItem);*/
|
|
|
+ else if (childItem->assetType == String("MaterialAsset"))
|
|
|
+ processMaterialAsset(childItem);
|
|
|
+ /*else if (childItem->assetType == String("ShapeAnimationAsset"))
|
|
|
+ ShapeAnimationAsset::prepareAssetForImport(this, childItem);*/
|
|
|
+
|
|
|
+ childItem->processed = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ //try recusing on the children(if any)
|
|
|
+ processImportAssets(childItem);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //If our hierarchy changed, it's because we did so during processing
|
|
|
+ //so we'll loop back through again until everything has been processed
|
|
|
+ if (assetHeirarchyChanged)
|
|
|
+ processImportAssets();
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::processImageAsset(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Image for Import: %s", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ if ((activeImportConfig.GenerateMaterialOnImport && assetItem->parentAssetItem == nullptr) || assetItem->parentAssetItem != nullptr)
|
|
|
+ {
|
|
|
+ //find our suffix match, if any
|
|
|
+ String noSuffixName = assetItem->assetName;
|
|
|
+ String suffixType;
|
|
|
+ String suffix = parseImageSuffixes(assetItem->assetName, &suffixType);
|
|
|
+ if (suffix.isNotEmpty())
|
|
|
+ {
|
|
|
+ assetItem->imageSuffixType = suffixType;
|
|
|
+ S32 suffixPos =assetItem->assetName.find(suffix, 0, String::NoCase|String::Left);
|
|
|
+ noSuffixName = assetItem->assetName.substr(0, suffixPos);
|
|
|
+ }
|
|
|
+
|
|
|
+ //We try to automatically populate materials under the naming convention: materialName: Rock, image maps: Rock_Albedo, Rock_Normal, etc
|
|
|
+
|
|
|
+ AssetImportObject* materialAsset = findImportingAssetByName(noSuffixName);
|
|
|
+ if (materialAsset != nullptr && materialAsset->assetType != String("MaterialAsset"))
|
|
|
+ {
|
|
|
+ //We may have a situation where an asset matches the no-suffix name, but it's not a material asset. Ignore this
|
|
|
+ //asset item for now
|
|
|
+ materialAsset = nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ //If we didn't find a matching material asset in our current items, we'll make one now
|
|
|
+ if (materialAsset == nullptr)
|
|
|
+ {
|
|
|
+ if (!assetItem->filePath.isEmpty())
|
|
|
+ {
|
|
|
+ materialAsset = addImportingAsset("MaterialAsset", "", nullptr, noSuffixName);
|
|
|
+ //Add the material into the primary list of importing assets
|
|
|
+ importingAssets.push_back(materialAsset);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //Not that, one way or another, we have the generated material asset, lets move on to associating our image with it
|
|
|
+ if (materialAsset != nullptr && materialAsset != assetItem->parentAssetItem)
|
|
|
+ {
|
|
|
+ if (assetItem->parentAssetItem != nullptr)
|
|
|
+ {
|
|
|
+ //If the image had an existing parent, it gets removed from that parent's child item list
|
|
|
+ assetItem->parentAssetItem->childAssetItems.remove(assetItem);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //If it didn't have one, we're going to pull it from the importingAssets list
|
|
|
+ importingAssets.remove(assetItem);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Now we can add it to the correct material asset
|
|
|
+ materialAsset->childAssetItems.push_back(assetItem);
|
|
|
+ assetItem->parentAssetItem = materialAsset;
|
|
|
+
|
|
|
+ assetHeirarchyChanged = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Now to do some cleverness. If we're generating a material, we can parse like assets being imported(similar filenames) but different suffixes
|
|
|
+ //If we find these, we'll just populate into the original's material
|
|
|
+
|
|
|
+ //if we need to append the diffuse suffix and indeed didn't find a suffix on the name, do that here
|
|
|
+ if (suffixType.isEmpty())
|
|
|
+ {
|
|
|
+ if (activeImportConfig.UseDiffuseSuffixOnOriginImage)
|
|
|
+ {
|
|
|
+ String diffuseToken = StringUnit::getUnit(activeImportConfig.DiffuseTypeSuffixes, 0, ",;");
|
|
|
+ assetItem->assetName = assetItem->assetName + diffuseToken;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //We need to ensure that our image asset doesn't match the same name as the material asset, so if we're not trying to force the diffuse suffix
|
|
|
+ //we'll give it a generic one
|
|
|
+ if (materialAsset->assetName.compare(assetItem->assetName) == 0)
|
|
|
+ {
|
|
|
+ assetItem->assetName = assetItem->assetName + "_image";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ suffixType = "Albedo";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (suffixType.isNotEmpty())
|
|
|
+ {
|
|
|
+ assetItem->imageSuffixType = suffixType;
|
|
|
+
|
|
|
+ //otherwise, if we have some sort of suffix, we'll want to figure out if we've already got an existing material, and should append to it
|
|
|
+ if (activeImportConfig.PopulateMaterialMaps)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ assetItem->processed = true;
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Material for Import: %s", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ String filePath = assetItem->filePath.getFullPath();
|
|
|
+ String fileName = assetItem->filePath.getFileName();
|
|
|
+ String fileExt = assetItem->filePath.getExtension();
|
|
|
+ const char* assetName = assetItem->assetName.c_str();
|
|
|
+
|
|
|
+ assetItem->generatedAsset = true;
|
|
|
+
|
|
|
+ if (activeImportConfig.IgnoreMaterials.isNotEmpty())
|
|
|
+ {
|
|
|
+ U32 ignoredMatNameCount = StringUnit::getUnitCount(activeImportConfig.IgnoreMaterials, ".;");
|
|
|
+ for (U32 i = 0; i < ignoredMatNameCount; i++)
|
|
|
+ {
|
|
|
+ String ignoredName = StringUnit::getUnit(activeImportConfig.IgnoreMaterials, i, ".;");
|
|
|
+ if (FindMatch::isMatch(ignoredName.c_str(), assetName, false))
|
|
|
+ {
|
|
|
+ assetItem->skip = true;
|
|
|
+
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Material %s has been ignored due to it's name being listed in the IgnoreMaterials list in the Import Config.", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (activeImportConfig.PopulateMaterialMaps)
|
|
|
+ {
|
|
|
+ //If we're trying to populate the rest of our material maps, we need to go looking
|
|
|
+ }
|
|
|
+
|
|
|
+ assetItem->processed = true;
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::processShapeAsset(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Shape for Import: %s", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ String filePath = assetItem->filePath.getFullPath();
|
|
|
+ String fileName = assetItem->filePath.getFileName();
|
|
|
+ String fileExt = assetItem->filePath.getExtension();
|
|
|
+ const char* assetName = assetItem->assetName.c_str();
|
|
|
+
|
|
|
+ if (assetItem->shapeInfo == nullptr)
|
|
|
+ {
|
|
|
+ GuiTreeViewCtrl* shapeInfo = new GuiTreeViewCtrl();
|
|
|
+ shapeInfo->registerObject();
|
|
|
+
|
|
|
+ if (fileExt.compare("dae") == 0)
|
|
|
+ {
|
|
|
+ enumColladaForImport(filePath, shapeInfo, false);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Check if a cached DTS is available => no need to import the source file
|
|
|
+ // if we can load the DTS instead
|
|
|
+
|
|
|
+ AssimpShapeLoader loader;
|
|
|
+ loader.fillGuiTreeView(filePath.c_str(), shapeInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ assetItem->shapeInfo = shapeInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ S32 meshCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_meshCount"), nullptr));
|
|
|
+ S32 shapeItem = assetItem->shapeInfo->findItemByName("Meshes");
|
|
|
+
|
|
|
+ S32 animCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_animCount"), nullptr));
|
|
|
+ S32 animItem = assetItem->shapeInfo->findItemByName("Animations");
|
|
|
+
|
|
|
+ S32 materialCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_materialCount"), nullptr));
|
|
|
+ S32 matItem = assetItem->shapeInfo->findItemByName("Materials");
|
|
|
+
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), " Shape Info: Mesh Count: %i | Material Count: %i | Anim Count: %i", meshCount, animCount, materialCount);
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ if (activeImportConfig.ImportMesh && meshCount > 0)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (activeImportConfig.ImportAnimations && animCount > 0)
|
|
|
+ {
|
|
|
+ //If we have animations but no meshes, then this is a pure animation file so we can swap the asset type here
|
|
|
+ if (meshCount == 0)
|
|
|
+ {
|
|
|
+ //assetItem->assetType = "ShapeAnimation";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (activeImportConfig.ImportMaterials && materialCount > 0)
|
|
|
+ {
|
|
|
+ S32 materialId = assetItem->shapeInfo->getChildItem(matItem);
|
|
|
+ processShapeMaterialInfo(assetItem, materialId);
|
|
|
+
|
|
|
+ materialId = assetItem->shapeInfo->getNextSiblingItem(materialId);
|
|
|
+ while (materialId != 0)
|
|
|
+ {
|
|
|
+ processShapeMaterialInfo(assetItem, materialId);
|
|
|
+ materialId = assetItem->shapeInfo->getNextSiblingItem(materialId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ assetItem->processed = true;
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 materialItemId)
|
|
|
+{
|
|
|
+ String matName = assetItem->shapeInfo->getItemText(materialItemId);
|
|
|
+
|
|
|
+ Torque::Path filePath = assetItem->shapeInfo->getItemValue(materialItemId);
|
|
|
+ if (filePath.getFullFileName().isNotEmpty())
|
|
|
+ {
|
|
|
+ if (!Platform::isFile(filePath.getFullFileName()))
|
|
|
+ {
|
|
|
+ //could be a stale path reference, such as if it was downloaded elsewhere. Trim to just the filename and see
|
|
|
+ //if we can find it there
|
|
|
+ String shapePathBase = assetItem->filePath.getPath();
|
|
|
+
|
|
|
+ String matFilePath = filePath.getFileName() + "." + filePath.getExtension();
|
|
|
+ //trim (not found) if needbe
|
|
|
+ /*
|
|
|
+ %suffixPos = strpos(strlwr(%filename), " (not found)", 0);
|
|
|
+ %filename = getSubStr(%filename, 0, %suffixPos);
|
|
|
+ */
|
|
|
+
|
|
|
+ String testFileName = shapePathBase + "/" + matFilePath;
|
|
|
+ if (Platform::isFile(testFileName))
|
|
|
+ {
|
|
|
+ filePath = testFileName;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ AssetImportObject* matAssetItem = addImportingAsset("MaterialAsset", "", assetItem, matName);
|
|
|
+ addImportingAsset("ImageAsset", filePath, matAssetItem, "");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /*
|
|
|
+ //check to see if it's actually just a flat color
|
|
|
+ if(getWordCount(%filePath) == 4 && getWord(%filePath, 0) $= "Color:")
|
|
|
+ {
|
|
|
+ AssetBrowser.addImportingAsset("MaterialAsset", %matName, %assetItem);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //we need to try and find our material, since the shapeInfo wasn't able to find it automatically
|
|
|
+ %filePath = findImageFile(filePath(%assetItem.filePath), %matName);
|
|
|
+ if(%filePath !$= "" && isFile(%filePath))
|
|
|
+ AssetBrowser.addImportingAsset("MaterialAsset", %filePath, %assetItem);
|
|
|
+ else
|
|
|
+ AssetBrowser.addImportingAsset("MaterialAsset", filePath(%assetItem.filePath) @ "/" @ %matName, %assetItem);
|
|
|
+ }
|
|
|
+ */
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// Validation
|
|
|
+//
|
|
|
+
|
|
|
+bool AssetImporter::validateAssets()
|
|
|
+{
|
|
|
+ importIssues = false;
|
|
|
+
|
|
|
+ resetAssetValidationStatus();
|
|
|
+
|
|
|
+ for (U32 i = 0; i < importingAssets.size(); i++)
|
|
|
+ {
|
|
|
+ validateAsset(importingAssets[i]);
|
|
|
+ resolveAssetItemIssues(importingAssets[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return importIssues;
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::validateAsset(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ if (assetItem->skip)
|
|
|
+ return;
|
|
|
+
|
|
|
+ bool hasCollision = checkAssetForCollision(assetItem);
|
|
|
+
|
|
|
+ if (hasCollision)
|
|
|
+ {
|
|
|
+ importIssues = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isReimport)
|
|
|
+ {
|
|
|
+ AssetQuery aQuery;
|
|
|
+ U32 numAssetsFound = AssetDatabase.findAllAssets(&aQuery);
|
|
|
+
|
|
|
+ bool hasCollision = false;
|
|
|
+ for (U32 i = 0; i < numAssetsFound; i++)
|
|
|
+ {
|
|
|
+ StringTableEntry assetId = aQuery.mAssetList[i];
|
|
|
+
|
|
|
+ ModuleDefinition* moduleDef = AssetDatabase.getAssetModuleDefinition(assetId);
|
|
|
+
|
|
|
+ if (moduleDef->getModuleId() != StringTable->insert(targetModuleId.c_str()))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ StringTableEntry assetName = AssetDatabase.getAssetName(assetId);
|
|
|
+
|
|
|
+ if (assetName == StringTable->insert(assetItem->assetName.c_str()))
|
|
|
+ {
|
|
|
+ hasCollision = true;
|
|
|
+ assetItem->status = "Error";
|
|
|
+ assetItem->statusType = "DuplicateAsset";
|
|
|
+ assetItem->statusInfo = "Duplicate asset names found within the target module!\nAsset \"" + assetItem->assetName + "\" of type \"" + assetItem->assetType + "\" has a matching name.\nPlease rename it and try again!";
|
|
|
+
|
|
|
+ //log it
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Asset %s has an identically named asset in the target module.", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!assetItem->filePath.isEmpty() && !assetItem->generatedAsset && !Platform::isFile(assetItem->filePath.getFullPath().c_str()))
|
|
|
+ {
|
|
|
+ assetItem->status = "Error";
|
|
|
+ assetItem->statusType = "MissingFile";
|
|
|
+ assetItem->statusInfo = "Unable to find file to be imported with provided path: " + assetItem->filePath + "\n Please select a valid file.";
|
|
|
+
|
|
|
+ //log it
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Asset %s's file at %s was not found.", assetItem->assetName.c_str(), assetItem->filePath.getFullPath().c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (assetItem->status == String("Warning"))
|
|
|
+ {
|
|
|
+ if (activeImportConfig.WarningsAsErrors)
|
|
|
+ {
|
|
|
+ assetItem->status = "Error";
|
|
|
+
|
|
|
+ //log it
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Import configuration has treated an import warning as an error.", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (assetItem->status == String("Error"))
|
|
|
+ importIssues = true;
|
|
|
+
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ validateAsset(assetItem->childAssetItems[i]);
|
|
|
+ resolveAssetItemIssues(assetItem->childAssetItems[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::resetAssetValidationStatus(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ if (assetItem == nullptr)
|
|
|
+ {
|
|
|
+ for (U32 i = 0; i < importingAssets.size(); i++)
|
|
|
+ {
|
|
|
+ if (importingAssets[i]->skip)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ importingAssets[i]->status = "";
|
|
|
+ importingAssets[i]->statusType = "";
|
|
|
+ importingAssets[i]->statusInfo = "";
|
|
|
+
|
|
|
+ //If it wasn't a match, try recusing on the children(if any)
|
|
|
+ resetAssetValidationStatus(importingAssets[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //this is the child recursing section
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ if (assetItem->childAssetItems[i]->skip)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ assetItem->childAssetItems[i]->status = "";
|
|
|
+ assetItem->childAssetItems[i]->statusType = "";
|
|
|
+ assetItem->childAssetItems[i]->statusInfo = "";
|
|
|
+
|
|
|
+ //If it wasn't a match, try recusing on the children(if any)
|
|
|
+ resetAssetValidationStatus(assetItem->childAssetItems[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool AssetImporter::checkAssetForCollision(AssetImportObject* assetItemToCheck, AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ bool results = false;
|
|
|
+
|
|
|
+ if (assetItem == nullptr)
|
|
|
+ {
|
|
|
+ for (U32 i = 0; i < importingAssets.size(); i++)
|
|
|
+ {
|
|
|
+ if (importingAssets[i]->skip)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if ((assetItemToCheck->assetName.compare(importingAssets[i]->assetName) == 0) && (assetItemToCheck->getId() != importingAssets[i]->getId()))
|
|
|
+ {
|
|
|
+ //we do have a collision, note the collsion and bail out
|
|
|
+ assetItemToCheck->status = "Warning";
|
|
|
+ assetItemToCheck->statusType = "DuplicateImportAsset";
|
|
|
+ assetItemToCheck->statusInfo = "Duplicate asset names found with importing assets!\nAsset \"" + importingAssets[i]->assetName + "\" of the type \"" + importingAssets[i]->assetType + "\" and \"" +
|
|
|
+ assetItemToCheck->assetName + "\" of the type \"" + assetItemToCheck->assetType + "\" have matching names.\nPlease rename one of them.";
|
|
|
+
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Warning! Asset %s, type %s has a naming collision with another importing asset: %s, type %s",
|
|
|
+ assetItemToCheck->assetName.c_str(), assetItemToCheck->assetType.c_str(),
|
|
|
+ importingAssets[i]->assetName.c_str(), importingAssets[i]->assetType.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ //If it wasn't a match, try recusing on the children(if any)
|
|
|
+ results = checkAssetForCollision(assetItemToCheck, importingAssets[i]);
|
|
|
+ if (results)
|
|
|
+ return results;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //this is the child recursing section
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ if (assetItem->childAssetItems[i]->skip)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if ((assetItemToCheck->assetName.compare(assetItem->childAssetItems[i]->assetName) == 0) && (assetItemToCheck->getId() != assetItem->childAssetItems[i]->getId()))
|
|
|
+ {
|
|
|
+ //we do have a collision, note the collsion and bail out
|
|
|
+ assetItemToCheck->status = "Warning";
|
|
|
+ assetItemToCheck->statusType = "DuplicateImportAsset";
|
|
|
+ assetItemToCheck->statusInfo = "Duplicate asset names found with importing assets!\nAsset \"" + assetItem->assetName + "\" of the type \"" + assetItem->assetType + "\" and \"" +
|
|
|
+ assetItemToCheck->assetName + "\" of the type \"" + assetItemToCheck->assetType + "\" have matching names.\nPlease rename one of them.";
|
|
|
+
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Warning! Asset %s, type %s has a naming collision with another importing asset: %s, type %s",
|
|
|
+ assetItemToCheck->assetName.c_str(), assetItemToCheck->assetType.c_str(),
|
|
|
+ importingAssets[i]->assetName.c_str(), importingAssets[i]->assetType.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ //If it wasn't a match, try recusing on the children(if any)
|
|
|
+ results = checkAssetForCollision(assetItemToCheck, assetItem->childAssetItems[i]);
|
|
|
+ if (results)
|
|
|
+ return results;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return results;
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ if (assetItem->statusType == String("DuplicateImportAsset") || assetItem->statusType == String("DuplicateAsset"))
|
|
|
+ {
|
|
|
+ String humanReadableReason = assetItem->statusType == String("DuplicateImportAsset") ? "Importing asset was duplicate of another importing asset" : "Importing asset was duplicate of an existing asset";
|
|
|
+
|
|
|
+ //get the config value for duplicateAutoResolution
|
|
|
+ if (activeImportConfig.DuplicatAutoResolution == String("AutoPrune"))
|
|
|
+ {
|
|
|
+ //delete the item
|
|
|
+ deleteImportingAsset(assetItem);
|
|
|
+
|
|
|
+ //log it's deletion
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was autoprined due to %s as part of the Import Configuration", assetItem->assetName.c_str(), humanReadableReason.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ importIssues = false;
|
|
|
+ }
|
|
|
+ else if (activeImportConfig.DuplicatAutoResolution == String("AutoRename"))
|
|
|
+ {
|
|
|
+ //Set trailing number
|
|
|
+ String renamedAssetName = assetItem->assetName;
|
|
|
+ renamedAssetName = Sim::getUniqueName(renamedAssetName.c_str());
|
|
|
+
|
|
|
+ //Log it's renaming
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was renamed due to %s as part of the Import Configuration", assetItem->assetName.c_str(), humanReadableReason.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was renamed to %s", assetItem->assetName.c_str(), renamedAssetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ assetItem->assetName = renamedAssetName;
|
|
|
+
|
|
|
+ //Whatever status we had prior is no longer relevent, so reset the status
|
|
|
+ resetAssetValidationStatus(assetItem);
|
|
|
+ importIssues = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (assetItem->statusType == String("MissingFile"))
|
|
|
+ {
|
|
|
+ //Trigger callback to look?
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// Importing
|
|
|
+//
|
|
|
+StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath)
|
|
|
+{
|
|
|
+ String assetType = getAssetTypeByFile(filePath);
|
|
|
+
|
|
|
+ if (assetType == String("Folder") || assetType == String("Zip"))
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is a folder or zip.", filePath.getFullPath().c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return StringTable->EmptyString();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (assetType.isEmpty())
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is of an unrecognized/unsupported type.", filePath.getFullPath().c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return StringTable->EmptyString();
|
|
|
+ }
|
|
|
+
|
|
|
+ //Find out if the filepath has an associated module to it. If we're importing in-place, it needs to be within a module's directory
|
|
|
+ ModuleDefinition* targetModuleDef = getModuleFromPath(filePath);
|
|
|
+
|
|
|
+ if (targetModuleDef == nullptr)
|
|
|
+ {
|
|
|
+ //log it
|
|
|
+ return StringTable->EmptyString();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ targetModuleId = targetModuleDef->getModuleId();
|
|
|
+ }
|
|
|
+
|
|
|
+ //set our path
|
|
|
+ targetPath = filePath.getPath();
|
|
|
+
|
|
|
+ //use a default import config
|
|
|
+ activeImportConfig = AssetImportConfig();
|
|
|
+
|
|
|
+ AssetImportObject* assetItem = addImportingAsset(assetType, filePath, nullptr, "");
|
|
|
+
|
|
|
+ importingAssets.push_back(assetItem);
|
|
|
+
|
|
|
+ processImportAssets();
|
|
|
+
|
|
|
+ bool hasIssues = validateAssets();
|
|
|
+
|
|
|
+ if (hasIssues)
|
|
|
+ {
|
|
|
+ //log it
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Import process has failed due to issues discovered during validation!");
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ importAssets();
|
|
|
+ }
|
|
|
+
|
|
|
+#if TORQUE_DEBUG
|
|
|
+ for (U32 i = 0; i < activityLog.size(); i++)
|
|
|
+ {
|
|
|
+ Con::printf(activityLog[i].c_str());
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (hasIssues)
|
|
|
+ {
|
|
|
+ return StringTable->EmptyString();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ String assetId = targetModuleId + ":" + assetItem->assetName;
|
|
|
+ return StringTable->insert(assetId.c_str());
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void AssetImporter::importAssets(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ ModuleDefinition* moduleDef = ModuleDatabase.findModule(targetModuleId.c_str(), 1);
|
|
|
+
|
|
|
+ if (moduleDef == nullptr)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Unable to find moduleId %s", targetModuleId.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (assetItem == nullptr)
|
|
|
+ {
|
|
|
+ for (U32 i = 0; i < importingAssets.size(); i++)
|
|
|
+ {
|
|
|
+ if (importingAssets[i]->skip)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ Torque::Path assetPath;
|
|
|
+ if (importingAssets[i]->assetType == String("ImageAsset"))
|
|
|
+ assetPath = importImageAsset(importingAssets[i]);
|
|
|
+ else if (importingAssets[i]->assetType == String("ShapeAsset"))
|
|
|
+ assetPath = importShapeAsset(importingAssets[i]);
|
|
|
+ /*else if (importingAssets[i]->assetType == String("SoundAsset"))
|
|
|
+ assetPath = SoundAsset::importAsset(importingAssets[i]);*/
|
|
|
+ else if (importingAssets[i]->assetType == String("MaterialAsset"))
|
|
|
+ assetPath = importMaterialAsset(importingAssets[i]);
|
|
|
+ /*else if (importingAssets[i]->assetType == String("ShapeAnimationAsset"))
|
|
|
+ assetPath = ShapeAnimationAsset::importAsset(importingAssets[i]);*/
|
|
|
+
|
|
|
+ if (assetPath.isEmpty())
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Import attempt of %s failed, so skipping asset.", importingAssets[i]->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //If we got a valid filepath back from the import action, then we know we're good to go and we can go ahead and register the asset!
|
|
|
+ if (!isReimport)
|
|
|
+ {
|
|
|
+ bool registerSuccess = AssetDatabase.addDeclaredAsset(moduleDef, assetPath.getFullPath().c_str());
|
|
|
+
|
|
|
+ if (!registerSuccess)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to successfully register new asset at path %s to moduleId %s", assetPath.getFullPath().c_str(), targetModuleId.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ String assetId = importingAssets[i]->moduleName + ":" + importingAssets[i]->assetName;
|
|
|
+ bool refreshSuccess = AssetDatabase.refreshAsset(assetId.c_str());
|
|
|
+
|
|
|
+ if (!refreshSuccess)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to refresh reimporting asset %s.", importingAssets[i]->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //recurse if needed
|
|
|
+ importAssets(importingAssets[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //this is the child recursing section
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ AssetImportObject* childItem = assetItem->childAssetItems[i];
|
|
|
+
|
|
|
+ if (childItem->skip)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ Torque::Path assetPath;
|
|
|
+ if (childItem->assetType == String("ImageAsset"))
|
|
|
+ assetPath = importImageAsset(childItem);
|
|
|
+ else if (childItem->assetType == String("ShapeAsset"))
|
|
|
+ assetPath = importShapeAsset(childItem);
|
|
|
+ /*else if (childItem->assetType == String("SoundAsset"))
|
|
|
+ assetPath = SoundAsset::importAsset(childItem);*/
|
|
|
+ else if (childItem->assetType == String("MaterialAsset"))
|
|
|
+ assetPath = importMaterialAsset(childItem);
|
|
|
+ /*else if (childItem->assetType == String("ShapeAnimationAsset"))
|
|
|
+ assetPath = ShapeAnimationAsset::importAsset(childItem);*/
|
|
|
+
|
|
|
+ if (assetPath.isEmpty())
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Import attempt of %s failed, so skipping asset.", childItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //If we got a valid filepath back from the import action, then we know we're good to go and we can go ahead and register the asset!
|
|
|
+ if (!isReimport)
|
|
|
+ {
|
|
|
+ bool registerSuccess = AssetDatabase.addDeclaredAsset(moduleDef, assetPath.getFullPath().c_str());
|
|
|
+
|
|
|
+ if (!registerSuccess)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to successfully register new asset at path %s to moduleId %s", assetPath.getFullPath().c_str(), targetModuleId.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ String assetId = childItem->moduleName + ":" + childItem->assetName;
|
|
|
+ bool refreshSuccess = AssetDatabase.refreshAsset(assetId.c_str());
|
|
|
+
|
|
|
+ if (!refreshSuccess)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to refresh reimporting asset %s.", childItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //recurse if needed
|
|
|
+ importAssets(childItem);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// Type-specific import logic
|
|
|
+//
|
|
|
+
|
|
|
+Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Image Asset: %s", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ ImageAsset* newAsset = new ImageAsset();
|
|
|
+ newAsset->registerObject();
|
|
|
+
|
|
|
+ StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str());
|
|
|
+
|
|
|
+ String imageFileName = assetItem->filePath.getFileName() + "." + assetItem->filePath.getExtension();
|
|
|
+ String assetPath = targetPath + "/" + imageFileName;
|
|
|
+ String tamlPath = targetPath + "/" + assetName + ".asset.taml";
|
|
|
+ String originalPath = assetItem->filePath.getFullPath().c_str();
|
|
|
+
|
|
|
+ char qualifiedFromFile[2048];
|
|
|
+ char qualifiedToFile[2048];
|
|
|
+
|
|
|
+ Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
|
|
|
+ Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
|
|
|
+
|
|
|
+ newAsset->setAssetName(assetName);
|
|
|
+ newAsset->setImageFileName(imageFileName.c_str());
|
|
|
+ newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
|
|
+
|
|
|
+ ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(assetItem->imageSuffixType.c_str());
|
|
|
+ newAsset->setImageType(imageType);
|
|
|
+
|
|
|
+ Taml tamlWriter;
|
|
|
+ bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
|
|
|
+
|
|
|
+ if (!importSuccessful)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isReimport)
|
|
|
+ {
|
|
|
+ bool isInPlace = !dStrcmp(qualifiedFromFile, qualifiedToFile);
|
|
|
+
|
|
|
+ if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport))
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return tamlPath;
|
|
|
+}
|
|
|
+
|
|
|
+Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Material Asset: %s", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ MaterialAsset* newAsset = new MaterialAsset();
|
|
|
+ newAsset->registerObject();
|
|
|
+
|
|
|
+ StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str());
|
|
|
+
|
|
|
+ String tamlPath = targetPath + "/" + assetName + ".asset.taml";
|
|
|
+ String scriptName = assetItem->assetName + ".cs";
|
|
|
+ String scriptPath = targetPath + "/" + scriptName;
|
|
|
+ String originalPath = assetItem->filePath.getFullPath().c_str();
|
|
|
+
|
|
|
+ char qualifiedFromFile[2048];
|
|
|
+
|
|
|
+ Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
|
|
|
+
|
|
|
+ newAsset->setAssetName(assetName);
|
|
|
+ newAsset->setScriptFile(scriptName.c_str());
|
|
|
+ newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
|
|
+
|
|
|
+ //iterate through and write out the material maps dependencies
|
|
|
+ S32 dependencySlotId = 0;
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ AssetImportObject* childItem = assetItem->childAssetItems[i];
|
|
|
+
|
|
|
+ if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ char dependencyFieldName[64];
|
|
|
+ dSprintf(dependencyFieldName, 64, "imageMap%i", dependencySlotId);
|
|
|
+
|
|
|
+ char dependencyFieldDef[512];
|
|
|
+ dSprintf(dependencyFieldDef, 512, "@Asset=%s:%s", targetModuleId.c_str(), childItem->assetName.c_str());
|
|
|
+
|
|
|
+ newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
|
|
|
+
|
|
|
+ dependencySlotId++;
|
|
|
+ }
|
|
|
+
|
|
|
+ Taml tamlWriter;
|
|
|
+ bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
|
|
|
+
|
|
|
+ if (!importSuccessful)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ //build the PBRConfig file if we're flagged to and have valid image maps
|
|
|
+ if (activeImportConfig.CreatePBRConfig)
|
|
|
+ {
|
|
|
+ AssetImportObject* pbrConfigMap = nullptr;
|
|
|
+ AssetImportObject* roughnessMap = nullptr;
|
|
|
+ AssetImportObject* metalnessMap = nullptr;
|
|
|
+ AssetImportObject* aoMap = nullptr;
|
|
|
+
|
|
|
+ //We need to find any/all respective image maps for the given channels
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ AssetImportObject* childItem = assetItem->childAssetItems[i];
|
|
|
+
|
|
|
+ if (childItem->skip || childItem->assetType.compare("ImageAsset") != 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (childItem->imageSuffixType.compare("PBRConfig") == 0)
|
|
|
+ pbrConfigMap = childItem;
|
|
|
+ else if(childItem->imageSuffixType.compare("Roughness") == 0)
|
|
|
+ roughnessMap = childItem;
|
|
|
+ else if (childItem->imageSuffixType.compare("Metalness") == 0)
|
|
|
+ metalnessMap = childItem;
|
|
|
+ else if (childItem->imageSuffixType.compare("AO") == 0)
|
|
|
+ aoMap = childItem;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pbrConfigMap != nullptr && pbrConfigMap->generatedAsset)
|
|
|
+ {
|
|
|
+ if (roughnessMap != nullptr || metalnessMap != nullptr || aoMap != nullptr)
|
|
|
+ {
|
|
|
+ U32 channelKey[4] = { 0,1,2,3 };
|
|
|
+
|
|
|
+ GFX->getTextureManager()->saveCompositeTexture(aoMap->filePath.getFullPath(), roughnessMap->filePath.getFullPath(), metalnessMap->filePath.getFullPath(), "",
|
|
|
+ channelKey, pbrConfigMap->filePath.getFullPath(), &GFXTexturePersistentProfile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ FileObject* file = new FileObject();
|
|
|
+ file->registerObject();
|
|
|
+
|
|
|
+ //Now write the script file containing our material out
|
|
|
+ if (file->openForWrite(scriptPath.c_str()))
|
|
|
+ {
|
|
|
+ file->writeLine((U8*)"//--- OBJECT WRITE BEGIN ---");
|
|
|
+
|
|
|
+ char lineBuffer[1024];
|
|
|
+ dSprintf(lineBuffer, 1024, "singleton Material(%s) {", assetName);
|
|
|
+ file->writeLine((U8*)lineBuffer);
|
|
|
+
|
|
|
+ dSprintf(lineBuffer, 1024, " mapTo=\"%s\";", assetName);
|
|
|
+ file->writeLine((U8*)lineBuffer);
|
|
|
+
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ AssetImportObject* childItem = assetItem->childAssetItems[i];
|
|
|
+
|
|
|
+ if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ String mapFieldName = "";
|
|
|
+
|
|
|
+ if (childItem->imageSuffixType.compare("Albedo") == 0)
|
|
|
+ {
|
|
|
+ mapFieldName = "DiffuseMap";
|
|
|
+ }
|
|
|
+
|
|
|
+ String path = childItem->filePath.getFullFileName();
|
|
|
+ dSprintf(lineBuffer, 1024, " %s[0] = \"%s\";", mapFieldName.c_str(), path.c_str());
|
|
|
+ file->writeLine((U8*)lineBuffer);
|
|
|
+
|
|
|
+ dSprintf(lineBuffer, 1024, " %sAsset[0] = \"%s:%s\";", mapFieldName.c_str(), targetModuleId.c_str(), childItem->assetName.c_str());
|
|
|
+ file->writeLine((U8*)lineBuffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ file->writeLine((U8*)"};");
|
|
|
+ file->writeLine((U8*)"//--- OBJECT WRITE END ---");
|
|
|
+
|
|
|
+ file->close();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset script file %s", scriptPath.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ return tamlPath;
|
|
|
+}
|
|
|
+
|
|
|
+Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|
|
+{
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Shape Asset: %s", assetItem->assetName.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ ShapeAsset* newAsset = new ShapeAsset();
|
|
|
+ newAsset->registerObject();
|
|
|
+
|
|
|
+ StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str());
|
|
|
+
|
|
|
+ String shapeFileName = assetItem->filePath.getFileName() + "." + assetItem->filePath.getExtension();
|
|
|
+ String assetPath = targetPath + "/" + shapeFileName;
|
|
|
+ String constructorPath = targetPath + "/" + assetItem->filePath.getFileName() + ".cs";
|
|
|
+ String tamlPath = targetPath + "/" + assetName + ".asset.taml";
|
|
|
+ String originalPath = assetItem->filePath.getFullPath().c_str();
|
|
|
+ String originalConstructorPath = assetItem->filePath.getPath() + assetItem->filePath.getFileName() + ".cs";
|
|
|
+
|
|
|
+ char qualifiedFromFile[2048];
|
|
|
+ char qualifiedToFile[2048];
|
|
|
+ char qualifiedFromCSFile[2048];
|
|
|
+ char qualifiedToCSFile[2048];
|
|
|
+
|
|
|
+ Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
|
|
|
+ Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
|
|
|
+
|
|
|
+ Platform::makeFullPathName(originalConstructorPath.c_str(), qualifiedFromCSFile, sizeof(qualifiedFromCSFile));
|
|
|
+ Platform::makeFullPathName(constructorPath.c_str(), qualifiedToCSFile, sizeof(qualifiedToCSFile));
|
|
|
+
|
|
|
+ newAsset->setAssetName(assetName);
|
|
|
+ newAsset->setShapeFile(shapeFileName.c_str());
|
|
|
+ newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
|
|
+
|
|
|
+ //iterate through and write out the material maps dependencies
|
|
|
+ S32 dependencySlotId = 0;
|
|
|
+ for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
|
+ {
|
|
|
+ AssetImportObject* childItem = assetItem->childAssetItems[i];
|
|
|
+
|
|
|
+ if (childItem->skip || !childItem->processed)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (childItem->assetType.compare("MaterialAsset") == 0)
|
|
|
+ {
|
|
|
+ char dependencyFieldName[64];
|
|
|
+ dSprintf(dependencyFieldName, 64, "materialSlot%i", dependencySlotId);
|
|
|
+
|
|
|
+ char dependencyFieldDef[512];
|
|
|
+ dSprintf(dependencyFieldDef, 512, "@Asset=%s:%s", targetModuleId.c_str(), childItem->assetName.c_str());
|
|
|
+
|
|
|
+ newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
|
|
|
+
|
|
|
+ dependencySlotId++;
|
|
|
+ }
|
|
|
+ else if (childItem->assetType.compare("ShapeAnimationAsset") == 0)
|
|
|
+ {
|
|
|
+ char dependencyFieldName[64];
|
|
|
+ dSprintf(dependencyFieldName, 64, "animationSequence%i", dependencySlotId);
|
|
|
+
|
|
|
+ char dependencyFieldDef[512];
|
|
|
+ dSprintf(dependencyFieldDef, 512, "@Asset=%s:%s", targetModuleId.c_str(), childItem->assetName.c_str());
|
|
|
+
|
|
|
+ newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
|
|
|
+
|
|
|
+ dependencySlotId++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Taml tamlWriter;
|
|
|
+ bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
|
|
|
+
|
|
|
+ if (!importSuccessful)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ bool makeNewConstructor = true;
|
|
|
+ if (!isReimport)
|
|
|
+ {
|
|
|
+ bool isInPlace = !dStrcmp(qualifiedFromFile, qualifiedToFile);
|
|
|
+
|
|
|
+ if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport))
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromFile);
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isInPlace && Platform::isFile(qualifiedFromCSFile))
|
|
|
+ {
|
|
|
+ if(!dPathCopy(qualifiedFromCSFile, qualifiedToCSFile, !isReimport))
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromCSFile);
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //We successfully copied the original constructor file, so no extra work required
|
|
|
+ makeNewConstructor = false;
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Successfully copied original TSShape Constructor file %s", qualifiedFromCSFile);
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (makeNewConstructor)
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning creation of new TSShapeConstructor file: %s", qualifiedToCSFile);
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+
|
|
|
+ //find/create shape constructor
|
|
|
+ TSShapeConstructor* constructor = TSShapeConstructor::findShapeConstructor(Torque::Path(qualifiedToFile).getFullPath());
|
|
|
+ if (constructor == nullptr)
|
|
|
+ {
|
|
|
+ constructor = new TSShapeConstructor(qualifiedToFile);
|
|
|
+
|
|
|
+ String constructorName = assetItem->filePath.getFileName() + "_" + assetItem->filePath.getExtension().substr(0, 3);
|
|
|
+ constructorName.replace("-", "_");
|
|
|
+ constructorName.replace(".", "_");
|
|
|
+ constructorName = Sim::getUniqueName(constructorName.c_str());
|
|
|
+ constructor->registerObject(constructorName.c_str());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //now we write the import config logic into the constructor itself to ensure we load like we wanted it to
|
|
|
+ String neverImportMats;
|
|
|
+
|
|
|
+ if (activeImportConfig.IgnoreMaterials.isNotEmpty())
|
|
|
+ {
|
|
|
+ U32 ignoredMatNamesCount = StringUnit::getUnitCount(activeImportConfig.IgnoreMaterials, ",;");
|
|
|
+ for (U32 i = 0; i < ignoredMatNamesCount; i++)
|
|
|
+ {
|
|
|
+ if (i == 0)
|
|
|
+ neverImportMats = StringUnit::getUnit(activeImportConfig.IgnoreMaterials, i, ",;");
|
|
|
+ else
|
|
|
+ neverImportMats += String("\t") + StringUnit::getUnit(activeImportConfig.IgnoreMaterials, i, ",;");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (activeImportConfig.DoUpAxisOverride)
|
|
|
+ {
|
|
|
+ S32 upAxis;
|
|
|
+ if (activeImportConfig.UpAxisOverride.compare("X_AXIS") == 0)
|
|
|
+ {
|
|
|
+ upAxis = domUpAxisType::UPAXISTYPE_X_UP;
|
|
|
+ }
|
|
|
+ else if (activeImportConfig.UpAxisOverride.compare("Y_AXIS") == 0)
|
|
|
+ {
|
|
|
+ upAxis = domUpAxisType::UPAXISTYPE_Y_UP;
|
|
|
+ }
|
|
|
+ else if (activeImportConfig.UpAxisOverride.compare("Z_AXIS") == 0)
|
|
|
+ {
|
|
|
+ upAxis = domUpAxisType::UPAXISTYPE_Z_UP;
|
|
|
+ }
|
|
|
+ constructor->mOptions.upAxis = (domUpAxisType)upAxis;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (activeImportConfig.DoScaleOverride)
|
|
|
+ constructor->mOptions.unit = activeImportConfig.ScaleOverride;
|
|
|
+ else
|
|
|
+ constructor->mOptions.unit = -1;
|
|
|
+
|
|
|
+ enum eAnimTimingType
|
|
|
+ {
|
|
|
+ FrameCount = 0,
|
|
|
+ Seconds = 1,
|
|
|
+ Milliseconds = 1000
|
|
|
+ };
|
|
|
+
|
|
|
+ S32 lodType;
|
|
|
+ if (activeImportConfig.LODType.compare("TrailingNumber") == 0)
|
|
|
+ lodType = ColladaUtils::ImportOptions::eLodType::TrailingNumber;
|
|
|
+ else if (activeImportConfig.LODType.compare("SingleSize") == 0)
|
|
|
+ lodType = ColladaUtils::ImportOptions::eLodType::SingleSize;
|
|
|
+ else if (activeImportConfig.LODType.compare("DetectDTS") == 0)
|
|
|
+ lodType = ColladaUtils::ImportOptions::eLodType::DetectDTS;
|
|
|
+ constructor->mOptions.lodType = (ColladaUtils::ImportOptions::eLodType)lodType;
|
|
|
+
|
|
|
+ constructor->mOptions.singleDetailSize = activeImportConfig.convertLeftHanded;
|
|
|
+ constructor->mOptions.alwaysImport = activeImportConfig.ImportedNodes;
|
|
|
+ constructor->mOptions.neverImport = activeImportConfig.IgnoreNodes;
|
|
|
+ constructor->mOptions.alwaysImportMesh = activeImportConfig.ImportMeshes;
|
|
|
+ constructor->mOptions.neverImportMesh = activeImportConfig.IgnoreMeshes;
|
|
|
+ constructor->mOptions.ignoreNodeScale = activeImportConfig.IgnoreNodeScale;
|
|
|
+ constructor->mOptions.adjustCenter = activeImportConfig.AdjustCenter;
|
|
|
+ constructor->mOptions.adjustFloor = activeImportConfig.AdjustFloor;
|
|
|
+
|
|
|
+ constructor->mOptions.convertLeftHanded = activeImportConfig.convertLeftHanded;
|
|
|
+ constructor->mOptions.calcTangentSpace = activeImportConfig.calcTangentSpace;
|
|
|
+ constructor->mOptions.genUVCoords = activeImportConfig.genUVCoords;
|
|
|
+ constructor->mOptions.flipUVCoords = activeImportConfig.flipUVCoords;
|
|
|
+ constructor->mOptions.findInstances = activeImportConfig.findInstances;
|
|
|
+ constructor->mOptions.limitBoneWeights = activeImportConfig.limitBoneWeights;
|
|
|
+ constructor->mOptions.joinIdenticalVerts = activeImportConfig.JoinIdenticalVerts;
|
|
|
+ constructor->mOptions.reverseWindingOrder = activeImportConfig.reverseWindingOrder;
|
|
|
+ constructor->mOptions.invertNormals = activeImportConfig.invertNormals;
|
|
|
+ constructor->mOptions.removeRedundantMats = activeImportConfig.removeRedundantMats;
|
|
|
+
|
|
|
+ S32 animTimingType;
|
|
|
+ if (activeImportConfig.animTiming.compare("FrameCount") == 0)
|
|
|
+ animTimingType = ColladaUtils::ImportOptions::eAnimTimingType::FrameCount;
|
|
|
+ else if (activeImportConfig.animTiming.compare("Seconds") == 0)
|
|
|
+ animTimingType = ColladaUtils::ImportOptions::eAnimTimingType::Seconds;
|
|
|
+ else// (activeImportConfig.animTiming.compare("Milliseconds") == 0)
|
|
|
+ animTimingType = ColladaUtils::ImportOptions::eAnimTimingType::Milliseconds;
|
|
|
+
|
|
|
+ constructor->mOptions.animTiming = (ColladaUtils::ImportOptions::eAnimTimingType)animTimingType;
|
|
|
+
|
|
|
+ constructor->mOptions.animFPS = activeImportConfig.animFPS;
|
|
|
+
|
|
|
+ constructor->mOptions.neverImportMat = neverImportMats;
|
|
|
+
|
|
|
+ if (!constructor->save(constructorPath.c_str()))
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Failed to save shape constructor file to %s", constructorPath.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ dSprintf(importLogBuffer, sizeof(importLogBuffer), "Finished creating shape constructor file to %s", constructorPath.c_str());
|
|
|
+ activityLog.push_back(importLogBuffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return tamlPath;
|
|
|
+}
|