123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222 |
- #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"
- #include "core/resourceManager.h"
- #include "materials/materialManager.h"
- #include "console/persistenceManager.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() :
- DuplicateAutoResolution("AutoRename"),
- WarningsAsErrors(false),
- PreventImportWithErrors(true),
- AutomaticallyPromptMissingFiles(false),
- AddDirectoryPrefixToAssetName(false),
- ImportMesh(true),
- AlwaysAddShapeSuffix(false),
- AddedShapeSuffix("_shape"),
- UseManualShapeConfigRules(false),
- DoUpAxisOverride(false),
- UpAxisOverride("Z_AXIS"),
- DoScaleOverride(false),
- ScaleOverride(false),
- IgnoreNodeScale(false),
- AdjustCenter(false),
- AdjustFloor(false),
- CollapseSubmeshes(false),
- LODType("TrailingNumber"),
- AlwaysImportedNodes(""),
- AlwaysIgnoreNodes(""),
- AlwaysImportMeshes(""),
- AlwaysIgnoreMeshes(""),
- convertLeftHanded(false),
- calcTangentSpace(false),
- removeRedundantMats(false),
- genUVCoords(false),
- TransformUVs(false),
- flipUVCoords(false),
- findInstances(false),
- limitBoneWeights(false),
- JoinIdenticalVerts(false),
- reverseWindingOrder(false),
- invertNormals(false),
- ImportMaterials(true),
- AlwaysAddMaterialSuffix(true),
- AddedMaterialSuffix("_mat"),
- CreateORMConfig(true),
- UseDiffuseSuffixOnOriginImage(false),
- UseExistingMaterials(false),
- IgnoreMaterials(""),
- PopulateMaterialMaps(true),
- ImportAnimations(true),
- SeparateAnimations(false),
- SeparateAnimationPrefix(""),
- animTiming("FrameCount"),
- animFPS(false),
- GenerateCollisions(false),
- GenCollisionType(""),
- CollisionMeshPrefix(""),
- GenerateLOSCollisions(false),
- GenLOSCollisionType(""),
- LOSCollisionMeshPrefix(""),
- importImages(true),
- AlwaysAddImageSuffix(true),
- AddedImageSuffix("_image"),
- 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,_ORM,-ORM"),
- TextureFilteringMode("Bilinear"),
- UseMips(true),
- IsHDR(false),
- Scaling(false),
- ImagesCompressed(false),
- GenerateMaterialOnImport(true),
- importSounds(true),
- VolumeAdjust(false),
- PitchAdjust(false),
- SoundsCompressed(false),
- AlwaysAddSoundSuffix(false),
- AddedSoundSuffix("_sound")
- {
- }
- AssetImportConfig::~AssetImportConfig()
- {
- }
- bool AssetImportConfig::onAdd()
- {
- if (!Parent::onAdd())
- return false;
- return true;
- }
- void AssetImportConfig::onRemove()
- {
- Parent::onRemove();
- }
- /// Engine.
- void AssetImportConfig::initPersistFields()
- {
- Parent::initPersistFields();
- addGroup("General");
- addField("DuplicateAutoResolution", TypeRealString, Offset(DuplicateAutoResolution, AssetImportConfig), "Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename, FolderPrefix");
- 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");
- addField("AddDirectoryPrefixToAssetName", TypeBool, Offset(AddDirectoryPrefixToAssetName, AssetImportConfig), "Should the importer add the folder name as a prefix to the assetName. Helps prevent name collisions.");
- endGroup("General");
- addGroup("Meshes");
- addField("ImportMesh", TypeBool, Offset(ImportMesh, AssetImportConfig), "Indicates if this config supports importing meshes");
- addField("AlwaysAddShapeSuffix", TypeBool, Offset(AlwaysAddShapeSuffix, AssetImportConfig), "When importing a shape, this indicates if it should automatically add a standard suffix onto the name");
- addField("AddedShapeSuffix", TypeString, Offset(AddedShapeSuffix, AssetImportConfig), " If AlwaysAddShapeSuffix is on, this is the suffix to be added");
- addField("UseManualShapeConfigRules", TypeBool, Offset(UseManualShapeConfigRules, AssetImportConfig), "Indicates if this config should override the per-format sis files with the config's specific settings");
- addField("DoUpAxisOverride", TypeBool, Offset(DoUpAxisOverride, AssetImportConfig), "Indicates if the up axis in the model file should be overridden");
- addField("UpAxisOverride", TypeRealString, 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", TypeRealString, Offset(LODType, AssetImportConfig), "Indicates what LOD mode the model file should utilize to process out LODs. Options are TrailingNumber, DetectDTS, SingleSize");
- addField("AlwaysImportedNodes", TypeRealString, Offset(AlwaysImportedNodes, AssetImportConfig), " A list of what nodes should be guaranteed to be imported if found in the model file. Separated by either , or ;");
- addField("AlwaysIgnoreNodes", TypeRealString, Offset(AlwaysIgnoreNodes, AssetImportConfig), "A list of what nodes should be guaranteed to not be imported if found in the model file. Separated by either , or ;");
- addField("AlwaysImportMeshes", TypeRealString, Offset(AlwaysImportMeshes, AssetImportConfig), "A list of what mesh objects should be guaranteed to be imported if found in the model file. Separated by either , or ;");
- addField("AlwaysIgnoreMeshes", TypeRealString, Offset(AlwaysIgnoreMeshes, 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("ImportMaterials", TypeBool, Offset(ImportMaterials, AssetImportConfig), "Does this config allow for importing of materials");
- addField("AlwaysAddMaterialSuffix", TypeBool, Offset(AlwaysAddMaterialSuffix, AssetImportConfig), "When importing a material, this indicates if it should automatically add a standard suffix onto the name");
- addField("AddedMaterialSuffix", TypeString, Offset(AddedMaterialSuffix, AssetImportConfig), " If AlwaysAddMaterialSuffix is on, this is the suffix to be added");
- addField("CreateORMConfig", 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", TypeRealString, 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 ORMConfig maps respectively automatically");
- endGroup("Materials");
- addGroup("Animation");
- 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", TypeRealString, Offset(SeparateAnimationPrefix, AssetImportConfig), "If separating animations out from a source file, what prefix should be added to the names for grouping association");
- addField("animTiming", TypeRealString, 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("Animation");
- addGroup("Collision");
- addField("GenerateCollisions", TypeBool, Offset(GenerateCollisions, AssetImportConfig), "Does this configuration generate collision geometry when importing. (Not currently enabled)");
- addField("GenCollisionType", TypeRealString, Offset(GenCollisionType, AssetImportConfig), "What sort of collision geometry is generated. (Not currently enabled)");
- addField("CollisionMeshPrefix", TypeRealString, 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", TypeRealString, Offset(GenLOSCollisionType, AssetImportConfig), "What sort of Line of Sight collision geometry is generated. (Not currently enabled)");
- addField("LOSCollisionMeshPrefix", TypeRealString, 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("AlwaysAddImageSuffix", TypeBool, Offset(AlwaysAddImageSuffix, AssetImportConfig), "When importing an image, this indicates if it should automatically add a standard suffix onto the name");
- addField("AddedImageSuffix", TypeString, Offset(AddedImageSuffix, AssetImportConfig), " If AlwaysAddImageSuffix is on, this is the suffix to be added");
- addField("ImageType", TypeRealString, Offset(ImageType, AssetImportConfig), "What is the default ImageType images are imported as. Options are: N/A, Diffuse, Normal, Metalness, Roughness, AO, ORMConfig, GUI, Cubemap");
- addField("DiffuseTypeSuffixes", TypeRealString, 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", TypeRealString, 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", TypeRealString, 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", TypeRealString, 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", TypeRealString, 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", TypeRealString, 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", TypeRealString, Offset(PBRTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a ORMConfig map.\n e.g. _Composite or _PBR");
- addField("TextureFilteringMode", TypeRealString, 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
- DuplicateAutoResolution = configSettings->value(String(configName + "/General/DuplicateAutoResolution").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()));
- AddDirectoryPrefixToAssetName = dAtob(configSettings->value(String(configName + "/General/AddDirectoryPrefixToAssetName").c_str()));
- //Meshes
- ImportMesh = dAtob(configSettings->value(String(configName + "/Meshes/ImportMesh").c_str()));
- AlwaysAddShapeSuffix = dAtob(configSettings->value(String(configName + "/Meshes/AlwaysAddShapeSuffix").c_str()));
- AddedShapeSuffix = configSettings->value(String(configName + "/Meshes/AddedShapeSuffix").c_str());
- UseManualShapeConfigRules = dAtob(configSettings->value(String(configName + "/Meshes/UseManualShapeConfigRules").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());
- AlwaysImportedNodes = configSettings->value(String(configName + "/Meshes/AlwaysImportedNodes").c_str());
- AlwaysIgnoreNodes = configSettings->value(String(configName + "/Meshes/AlwaysIgnoreNodes").c_str());
- AlwaysImportMeshes = configSettings->value(String(configName + "/Meshes/AlwaysImportMeshes").c_str());
- AlwaysIgnoreMeshes = configSettings->value(String(configName + "/Meshes/AlwaysIgnoreMeshes").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()));
- AlwaysAddMaterialSuffix = dAtob(configSettings->value(String(configName + "/Materials/AlwaysAddMaterialSuffix").c_str()));
- AddedMaterialSuffix = configSettings->value(String(configName + "/Materials/AddedMaterialSuffix").c_str());
- CreateORMConfig = dAtob(configSettings->value(String(configName + "/Materials/CreateORMConfig").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/PopulateMaterialMaps").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()));
- AlwaysAddImageSuffix = dAtob(configSettings->value(String(configName + "/Images/AlwaysAddImageSuffix").c_str()));
- AddedImageSuffix = configSettings->value(String(configName + "/Images/AddedImageSuffix").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()));
- AlwaysAddSoundSuffix = dAtob(configSettings->value(String(configName + "/Sounds/AlwaysAddSoundSuffix").c_str()));
- AddedSoundSuffix = configSettings->value(String(configName + "/Sounds/AddedSoundSuffix").c_str());
- }
- void AssetImportConfig::CopyTo(AssetImportConfig* target) const
- {
- target->DuplicateAutoResolution = DuplicateAutoResolution;
- target->WarningsAsErrors = WarningsAsErrors;
- target->PreventImportWithErrors = PreventImportWithErrors;
- target->AutomaticallyPromptMissingFiles = AutomaticallyPromptMissingFiles;
- target->AddDirectoryPrefixToAssetName = AddDirectoryPrefixToAssetName;
- //Meshes
- target->ImportMesh = ImportMesh;
- target->AlwaysAddShapeSuffix = AlwaysAddShapeSuffix;
- target->AddedShapeSuffix = AddedShapeSuffix;
- target->UseManualShapeConfigRules = UseManualShapeConfigRules;
- target->DoUpAxisOverride = DoUpAxisOverride;
- target->UpAxisOverride = UpAxisOverride;
- target->DoScaleOverride = DoScaleOverride;
- target->ScaleOverride = ScaleOverride;
- target->IgnoreNodeScale = IgnoreNodeScale;
- target->AdjustCenter = AdjustCenter;
- target->AdjustFloor = AdjustFloor;
- target->CollapseSubmeshes = CollapseSubmeshes;
- target->LODType = LODType;
- target->AlwaysImportedNodes = AlwaysImportedNodes;
- target->AlwaysIgnoreNodes = AlwaysIgnoreNodes;
- target->AlwaysImportMeshes = AlwaysImportMeshes;
- target->AlwaysIgnoreMeshes = AlwaysIgnoreMeshes;
- //Assimp/Collada
- target->convertLeftHanded = convertLeftHanded;
- target->calcTangentSpace = calcTangentSpace;
- target->removeRedundantMats = removeRedundantMats;
- target->genUVCoords = genUVCoords;
- target->TransformUVs = TransformUVs;
- target->flipUVCoords = flipUVCoords;
- target->findInstances = findInstances;
- target->limitBoneWeights = limitBoneWeights;
- target->JoinIdenticalVerts = JoinIdenticalVerts;
- target->reverseWindingOrder = reverseWindingOrder;
- target->invertNormals = invertNormals;
- //Materials
- target->ImportMaterials = ImportMaterials;
- target->AlwaysAddMaterialSuffix = AlwaysAddMaterialSuffix;
- target->AddedMaterialSuffix = AddedMaterialSuffix;
- target->CreateORMConfig = CreateORMConfig;
- target->UseDiffuseSuffixOnOriginImage = UseDiffuseSuffixOnOriginImage;
- target->UseExistingMaterials = UseExistingMaterials;
- target->IgnoreMaterials = IgnoreMaterials;
- target->PopulateMaterialMaps = PopulateMaterialMaps;
- //Animations
- target->ImportAnimations = ImportAnimations;
- target->SeparateAnimations = SeparateAnimations;
- target->SeparateAnimationPrefix = SeparateAnimationPrefix;
- target->animTiming = animTiming;
- target->animFPS = animFPS;
- //Collisions
- target->GenerateCollisions = GenerateCollisions;
- target->GenCollisionType = GenCollisionType;
- target->CollisionMeshPrefix = CollisionMeshPrefix;
- target->GenerateLOSCollisions = GenerateLOSCollisions;
- target->GenLOSCollisionType = GenLOSCollisionType;
- target->LOSCollisionMeshPrefix = LOSCollisionMeshPrefix;
- //Images
- target->importImages = importImages;
- target->AlwaysAddImageSuffix = AlwaysAddImageSuffix;
- target->AddedImageSuffix = AddedImageSuffix;
- target->ImageType = ImageType;
- target->DiffuseTypeSuffixes = DiffuseTypeSuffixes;
- target->NormalTypeSuffixes = NormalTypeSuffixes;
- target->MetalnessTypeSuffixes = MetalnessTypeSuffixes;
- target->RoughnessTypeSuffixes = RoughnessTypeSuffixes;
- target->SmoothnessTypeSuffixes = SmoothnessTypeSuffixes;
- target->AOTypeSuffixes = AOTypeSuffixes;
- target->PBRTypeSuffixes = PBRTypeSuffixes;
- target->TextureFilteringMode = TextureFilteringMode;
- target->UseMips = UseMips;
- target->IsHDR = IsHDR;
- target->Scaling = Scaling;
- target->ImagesCompressed = ImagesCompressed;
- target->GenerateMaterialOnImport = GenerateMaterialOnImport;
- //Sounds
- target->VolumeAdjust = VolumeAdjust;
- target->PitchAdjust = PitchAdjust;
- target->SoundsCompressed = SoundsCompressed;
- target->AlwaysAddSoundSuffix = AlwaysAddSoundSuffix;
- target->AddedSoundSuffix = AddedSoundSuffix;
- }
- 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),
- importStatus(AssetImportObject::NotProcessed),
- generatedAsset(false),
- parentAssetItem(nullptr),
- tamlFilePath(""),
- imageSuffixType(""),
- shapeInfo(nullptr),
- filePathString(StringTable->EmptyString())
- {
- }
- AssetImportObject::~AssetImportObject()
- {
- }
- bool AssetImportObject::onAdd()
- {
- if (!Parent::onAdd())
- return false;
- return true;
- }
- void AssetImportObject::onRemove()
- {
- Parent::onRemove();
- }
- void AssetImportObject::initPersistFields()
- {
- Parent::initPersistFields();
- addField("assetType", TypeRealString, Offset(assetType, AssetImportObject), "What type is the importing asset");
- addProtectedField("filePath", TypeFilename, Offset(filePathString, AssetImportObject), &_setFilePath, &defaultProtectedGetFn, "What is the source file path of the importing asset");
- addField("assetName", TypeRealString, Offset(assetName, AssetImportObject), "What is the asset's name");
- addField("cleanAssetName", TypeRealString, Offset(cleanAssetName, AssetImportObject), "What is the original, unmodified by processing, asset name");
- addField("status", TypeRealString, Offset(status, AssetImportObject), "What is the current status of this asset item in it's import process");
- addField("statusType", TypeRealString, Offset(statusType, AssetImportObject), "If there is a warning or error status, what type is the condition for this asset item");
- addField("statusInfo", TypeRealString, 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("generatedAsset", TypeBool, Offset(generatedAsset, AssetImportObject), "Is this specific asset item generated as part of the import process of another item");
- addField("tamlFilePath", TypeRealString, Offset(tamlFilePath, AssetImportObject), "What is the ultimate asset taml file path for this import item");
- addField("imageType", TypeRealString, Offset(imageSuffixType, AssetImportObject), "Specific to ImageAsset type. What is the image asset's suffix type. Options are: Albedo, Normal, Roughness, AO, Metalness, ORMConfig");
- 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");
- }
- bool AssetImportObject::_setFilePath(void* obj, const char* index, const char* data)
- {
- AssetImportObject* importObj = static_cast<AssetImportObject*>(obj);
- importObj->setFilePath(StringTable->insert(data));
- return false;
- }
- void AssetImportObject::setFilePath(StringTableEntry pFilePath)
- {
- filePathString = pFilePath;
- filePath = Torque::Path(pFilePath);
- }
- 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(""),
- activeImportConfig(nullptr)
- {
- }
- AssetImporter::~AssetImporter()
- {
- }
- bool AssetImporter::onAdd()
- {
- if (!Parent::onAdd())
- return false;
- return true;
- }
- void AssetImporter::onRemove()
- {
- Parent::onRemove();
- }
- void AssetImporter::initPersistFields()
- {
- Parent::initPersistFields();
- addField("targetModuleId", TypeRealString, Offset(targetModuleId, AssetImporter), "The Id of the module the assets are to be imported into");
- addField("finalImportedAssetPath", TypeRealString, Offset(finalImportedAssetPath, AssetImporter), "The Id of the module the assets are to be imported into");
- addField("targetPath", TypeRealString, Offset(targetPath, AssetImporter), "The path any imported assets are placed in as their destination");
- }
- //
- // 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;
- }
- void AssetImporter::addImportingAssetItem(AssetImportObject* assetItem, AssetImportObject* parentItem)
- {
- if (assetItem == nullptr)
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Cannot add a null AssetImportObject to import session!");
- activityLog.push_back(importLogBuffer);
- return;
- }
- 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(assetItem);
- assetItem->parentAssetItem = parentItem;
- }
- else
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Added Importing Asset");
- activityLog.push_back(importLogBuffer);
- importingAssets.push_back(assetItem);
- }
- dSprintf(importLogBuffer, sizeof(importLogBuffer), " Asset Info: Name: %s | Type: %s", assetItem->assetName.c_str(), assetItem->assetType.c_str());
- activityLog.push_back(importLogBuffer);
- if (!assetItem->filePath.isEmpty())
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), " File: %s", assetItem->filePath.getFullPath().c_str());
- activityLog.push_back(importLogBuffer);
- }
- }
- 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();
- //sanitize
- assetName.replace(' ', '_');
- assetName.replace('~', '_');
- assetName.replace('`', '_');
- assetName.replace('-', '_');
- assetName.replace('*', '_');
- assetName.replace('-', '_');
- assetName.replace('+', '_');
- assetName.replace('&', '_');
- assetImportObj->assetType = assetType;
- assetImportObj->filePath = filePath;
- assetImportObj->filePathString = StringTable->insert(filePath.getFullPath().c_str());
- assetImportObj->assetName = assetName;
- assetImportObj->cleanAssetName = assetName;
- assetImportObj->moduleName = targetModuleId;
- assetImportObj->status = "";
- assetImportObj->statusType = "";
- assetImportObj->statusInfo = "";
- assetImportObj->dirty = false;
- assetImportObj->importStatus = AssetImportObject::NotProcessed;
- assetImportObj->generatedAsset = false;
- //If the config is marked to always set the directory prefix, do that now
- if (activeImportConfig->AddDirectoryPrefixToAssetName)
- {
- assetName = getFolderPrefixedName(assetImportObj);
- assetImportObj->assetName = assetName;
- assetImportObj->cleanAssetName = assetName;
- }
- 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);
- importingAssets.push_back(assetImportObj);
- }
- 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->importStatus = AssetImportObject::Skipped;
- //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)
- {
- Vector<AssetImportObject*> itemList = importingAssets;
- if (assetItem != nullptr)
- itemList = assetItem->childAssetItems;
- for (U32 i = 0; i < itemList.size(); i++)
- {
- if (itemList[i]->cleanAssetName == assetName)
- {
- return itemList[i];
- }
- //If it wasn't a match, try recusing on the children(if any)
- AssetImportObject* retItem = findImportingAssetByName(assetName, itemList[i]);
- if (retItem != nullptr)
- return retItem;
- }
- return nullptr;
- }
- ModuleDefinition* AssetImporter::getModuleFromPath(Torque::Path filePath)
- {
- // Use a relative path so modules on mounted file systems will be found.
- ModuleDefinition* moduleDef = ModuleDatabase.findModuleByFilePath(Platform::makeRelativePathName(filePath.getFullPath().c_str(), NULL));
- return moduleDef;
- }
- 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, "ORMConfig", 10);
- break;
- default:
- suffixList = "";
- }
- suffixTypeIdx++;
- U32 suffixCount = StringUnit::getUnitCount(suffixList, ",;\t");
- for (U32 i = 0; i < suffixCount; i++)
- {
- String suffix = StringUnit::getUnit(suffixList, i, ",;\t");
- String searchSuffix = String("*") + suffix;
- if (FindMatch::isMatch(searchSuffix.c_str(), assetName.c_str(), false))
- {
- //We have a match, so indicate as such
- S32 pos = assetName.length();
- pos -= searchSuffix.length();
- suffix = assetName.substr(pos+1);
- return suffix;
- }
- }
- }
- suffixType->clear();
- return "";
- }
- String AssetImporter::getAssetTypeByFile(Torque::Path filePath)
- {
- String fileExt = String::ToLower(filePath.getExtension());
- String fileName = String::ToLower(filePath.getFileName());
- if (fileExt == String("dts") && fileName.endsWith("cached"))
- return "";
- 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 "";
- }
- String AssetImporter::getTrueFilename(const String& fileName)
- {
- Torque::Path pth(fileName);
- String pattern = pth.getFullPath() + "*";
- static const String sSlash("/");
- Vector<String> findFilesResults;
- String sPattern(Torque::Path::CleanSeparators(pattern));
- if (sPattern.isEmpty())
- {
- Con::errorf("findFirstFile() requires a search pattern");
- return "";
- }
- char scriptFilenameBuffer[1024];
- if (!Con::expandScriptFilename(scriptFilenameBuffer, sizeof(scriptFilenameBuffer), sPattern.c_str()))
- {
- Con::errorf("findFirstFile() given initial directory cannot be expanded: '%s'", pattern.c_str());
- return "";
- }
- sPattern = String::ToString(scriptFilenameBuffer);
- String::SizeType slashPos = sPattern.find('/', 0, String::Right);
- // if(slashPos == String::NPos)
- // {
- // Con::errorf("findFirstFile() missing search directory or expression: '%s'", sPattern.c_str());
- // return -1;
- // }
- // Build the initial search path
- Torque::Path givenPath(Torque::Path::CompressPath(sPattern));
- givenPath.setFileName("*");
- givenPath.setExtension("*");
- if (givenPath.getPath().length() > 0 && givenPath.getPath().find('*', 0, String::Right) == givenPath.getPath().length() - 1)
- {
- // Deal with legacy searches of the form '*/*.*'
- String suspectPath = givenPath.getPath();
- String::SizeType newLen = suspectPath.length() - 1;
- if (newLen > 0 && suspectPath.find('/', 0, String::Right) == suspectPath.length() - 2)
- {
- --newLen;
- }
- givenPath.setPath(suspectPath.substr(0, newLen));
- }
- Torque::FS::FileSystemRef fs = Torque::FS::GetFileSystem(givenPath);
- //Torque::Path path = fs->mapTo(givenPath);
- Torque::Path path = givenPath;
- // Make sure that we have a root so the correct file system can be determined when using zips
- if (givenPath.isRelative())
- path = Torque::Path::Join(Torque::FS::GetCwd(), '/', givenPath);
- path.setFileName(String::EmptyString);
- path.setExtension(String::EmptyString);
- if (!Torque::FS::IsDirectory(path))
- {
- Con::errorf("findFirstFile() invalid initial search directory: '%s'", path.getFullPath().c_str());
- return "";
- }
- // Build the search expression
- const String expression(slashPos != String::NPos ? sPattern.substr(slashPos + 1) : sPattern);
- if (expression.isEmpty())
- {
- Con::errorf("findFirstFile() requires a search expression: '%s'", sPattern.c_str());
- return "";
- }
- S32 results = Torque::FS::FindByPattern(path, expression, false, findFilesResults, false);
- if (givenPath.isRelative() && results > 0)
- {
- // Strip the CWD out of the returned paths
- // MakeRelativePath() returns incorrect results (it adds a leading ..) so doing this the dirty way
- const String cwd = Torque::FS::GetCwd().getFullPath();
- for (S32 i = 0; i < findFilesResults.size(); ++i)
- {
- String str = findFilesResults[i];
- if (str.compare(cwd, cwd.length(), String::NoCase) == 0)
- str = str.substr(cwd.length());
- findFilesResults[i] = str;
- }
- }
- for (U32 i = 0; i < findFilesResults.size(); i++)
- {
- if (!findFilesResults[i].compare(fileName, 0, String::NoCase|String::Left))
- return findFilesResults[i];
- }
- return "";
- }
- void AssetImporter::resetImportSession(bool hardClearSession)
- {
- importingAssets.clear();
- activityLog.clear();
- if (hardClearSession)
- {
- originalImportingFiles.clear();
- }
- else
- {
- Vector<Torque::Path> tempImportingFiles = originalImportingFiles;
- originalImportingFiles.clear();
- for (U32 i = 0; i < tempImportingFiles.size(); i++)
- {
- addImportingFile(tempImportingFiles[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;
- }
- static bool enumDTSForImport(const char* shapePath, GuiTreeViewCtrl* tree)
- {
- // 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);
- Resource<TSShape> dtsShape = ResourceManager::get().load(shapePath);
- if (!dtsShape)
- return false;
- // 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 < dtsShape->objects.size(); i++)
- {
- tree->insertItem(nodesID, dtsShape->names[dtsShape->objects[i].nameIndex], "", "", 0, 0);
- stats.numMeshes++;
- }
- // Get material count
- for (S32 i = 0; i < dtsShape->materialList->size(); i++)
- {
- S32 matId = tree->insertItem(matsID, dtsShape->materialList->getMaterialName(i).c_str(), "", "", 0, 0);
- stats.numMaterials++;
- GFXTextureObject* difTex = dtsShape->materialList->getDiffuseTexture(i);
- if (difTex)
- {
- tree->insertItem(matId, difTex->getPath().c_str(), "", "", 0, 0);
- }
- }
- // Get animation count
- for (S32 i = 0; i < dtsShape->sequences.size(); i++)
- {
- tree->insertItem(animsID, dtsShape->names[dtsShape->sequences[i].nameIndex], "animation", "", 0, 0);
- stats.numClips++;
- }
- /*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;
- }
- }
- }*/
- F32 unit = 1.0f;
- // 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));
- 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 AssetImportConfig::loadSISFile(Torque::Path filePath)
- {
- String settingsFilePath = "Tools";
- Settings* editorSettings;
- //See if we can get our editor settings
- if (Sim::findObject("EditorSettings", editorSettings))
- {
- settingsFilePath = editorSettings->value("defaultSettingsPath", "Tools");
- }
- String fileExtension = filePath.getExtension();
- String settingsFile = settingsFilePath + "/" + fileExtension + ".sis";
- FileObject* fileObj = new FileObject();
- if (Platform::isFile(settingsFile))
- {
- if (!fileObj->readMemory(settingsFile.c_str()))
- {
- Con::errorf("AssetImporter::loadSISFile() - Error opening file to load settings: %s", settingsFile.c_str());
- fileObj->deleteObject();
- return;
- }
- }
- else
- {
- return;
- }
- String headerLine = (const char*)fileObj->readLine();
- if (headerLine.substr(0, 4).compare("SISV", 0U, String::NoCase) != 0)
- return; //not a sis file?
- while (!fileObj->isEOF())
- {
- const char* line = (const char*)fileObj->readLine();
- String key = StringUnit::getUnit(line, 0, "\t");
- String value = StringUnit::getUnit(line, 1, "\t");
- if (key.compare("DoUpAxisOverride", 0U, String::NoCase) == 0)
- DoUpAxisOverride = dAtob(value.c_str());
- else if (key.compare("UpAxisOverride", 0U, String::NoCase) == 0)
- UpAxisOverride = value.c_str();
- else if (key.compare("DoScaleOverride", 0U, String::NoCase) == 0)
- DoScaleOverride = dAtob(value.c_str());
- else if (key.compare("ScaleOverride", 0U, String::NoCase) == 0)
- ScaleOverride = dAtof(value.c_str());
- else if (key.compare("IgnoreNodeScale", 0U, String::NoCase) == 0)
- IgnoreNodeScale = dAtob(value.c_str());
- else if (key.compare("AdjustCenter", 0U, String::NoCase) == 0)
- AdjustCenter = dAtob(value.c_str());
- else if (key.compare("AdjustFloor", 0U, String::NoCase) == 0)
- AdjustFloor = dAtob(value.c_str());
- else if (key.compare("CollapseSubmeshes", 0U, String::NoCase) == 0)
- CollapseSubmeshes = dAtob(value.c_str());
- else if (key.compare("LODType", 0U, String::NoCase) == 0)
- LODType = value.c_str();
- else if (key.compare("AlwaysImportedNodes", 0U, String::NoCase) == 0)
- AlwaysImportedNodes = value.c_str();
- else if (key.compare("AlwaysIgnoreNodes", 0U, String::NoCase) == 0)
- AlwaysIgnoreNodes = value.c_str();
- else if (key.compare("AlwaysImportMeshes", 0U, String::NoCase) == 0)
- AlwaysImportMeshes = value.c_str();
- else if (key.compare("AlwaysIgnoreMeshes", 0U, String::NoCase) == 0)
- AlwaysIgnoreMeshes = value.c_str();
- else if (key.compare("convertLeftHanded", 0U, String::NoCase) == 0)
- convertLeftHanded = dAtob(value.c_str());
- else if (key.compare("calcTangentSpace", 0U, String::NoCase) == 0)
- calcTangentSpace = dAtob(value.c_str());
- else if (key.compare("removeRedundantMats", 0U, String::NoCase) == 0)
- removeRedundantMats = dAtob(value.c_str());
- else if (key.compare("genUVCoords", 0U, String::NoCase) == 0)
- genUVCoords = dAtob(value.c_str());
- else if (key.compare("TransformUVs", 0U, String::NoCase) == 0)
- TransformUVs = dAtob(value.c_str());
- else if (key.compare("flipUVCoords", 0U, String::NoCase) == 0)
- flipUVCoords = dAtob(value.c_str());
- else if (key.compare("findInstances", 0U, String::NoCase) == 0)
- findInstances = dAtob(value.c_str());
- else if (key.compare("limitBoneWeights", 0U, String::NoCase) == 0)
- limitBoneWeights = dAtob(value.c_str());
- else if (key.compare("JoinIdenticalVerts", 0U, String::NoCase) == 0)
- JoinIdenticalVerts = dAtob(value.c_str());
- else if (key.compare("reverseWindingOrder", 0U, String::NoCase) == 0)
- reverseWindingOrder = dAtob(value.c_str());
- else if (key.compare("invertNormals", 0U, String::NoCase) == 0)
- invertNormals = dAtob(value.c_str());
- }
- fileObj->close();
- fileObj->deleteObject();
- }
- void AssetImporter::processImportAssets(AssetImportObject* assetItem)
- {
- Vector<AssetImportObject*> itemList = importingAssets;
- if (assetItem != nullptr)
- itemList = assetItem->childAssetItems;
- assetHeirarchyChanged = false;
- for (U32 i = 0; i < itemList.size(); i++)
- {
- AssetImportObject* item = itemList[i];
- if (item->importStatus != AssetImportObject::NotProcessed)
- continue;
- //Sanitize before modifying our asset name(suffix additions, etc)
- if (item->assetName != item->cleanAssetName)
- item->assetName = item->cleanAssetName;
- //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"))
- {
- processSoundAsset(item);
- }
- else if (item->assetType == String("MaterialAsset"))
- {
- processMaterialAsset(item);
- }
- /*else if (item->assetType == String("ShapeAnimationAsset"))
- ShapeAnimationAsset::prepareAssetForImport(this, item);*/
- else
- {
- String processCommand = "process";
- processCommand += item->assetType;
- if(isMethod(processCommand.c_str()))
- Con::executef(this, processCommand.c_str(), item);
- }
- item->importStatus = AssetImportObject::Processed;
- //try recusing on the children(if any)
- processImportAssets(item);
- }
- //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", assetItem->filePath, nullptr, noSuffixName);
- }
- }
- //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, ",;\t");
- assetItem->assetName = assetItem->assetName + diffuseToken;
- assetItem->cleanAssetName = assetItem->assetName;
- }
- 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 && materialAsset->assetName.compare(assetItem->assetName) == 0) || activeImportConfig->AlwaysAddImageSuffix)
- {
- assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix;
- assetItem->cleanAssetName = assetItem->assetName;
- }
- }
- //Assume for abledo if it has no suffix matches
- assetItem->imageSuffixType = "Albedo";
- }
- else
- {
- }
- }
- else
- {
- //If we're processing an unaffiliated image without generating materials for it, we can check some other bits
- if (assetItem->parentAssetItem == nullptr)
- {
- if (assetItem->typeHint != String::EmptyString)
- {
- ImageAssetType type = ImageAsset::getImageTypeFromName(StringTable->insert(assetItem->typeHint.c_str()));
- if (type == ImageAssetType::GUI)
- {
- }
- }
- }
- }
- if(assetItem->assetName == assetItem->cleanAssetName && activeImportConfig->AlwaysAddImageSuffix)
- {
- assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix;
- assetItem->cleanAssetName = assetItem->assetName;
- }
- assetItem->importStatus = AssetImportObject::Processed;
- }
- 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, ",;\t");
- for (U32 i = 0; i < ignoredMatNameCount; i++)
- {
- String ignoredName = StringUnit::getUnit(activeImportConfig->IgnoreMaterials, i, ",;\t");
- if (FindMatch::isMatch(ignoredName.c_str(), assetName, false))
- {
- assetItem->importStatus = AssetImportObject::Skipped;
- 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->UseExistingMaterials)
- {
- //So if the material already exists, we should just use that. So first, let's find out if it already exists
- //check to see if the definition for this already exists
- StringTableEntry existingMatAsset = MaterialAsset::getAssetIdByMaterialName(StringTable->insert(assetName));
- if (existingMatAsset != StringTable->EmptyString() && existingMatAsset != StringTable->insert("Core_Rendering:NoMaterial"))
- {
- assetItem->importStatus = AssetImportObject::UseForDependencies;
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Material %s has been skipped because we already found an asset Id that uses that material definition. The found assetId is: %s", assetItem->assetName.c_str(), existingMatAsset);
- activityLog.push_back(importLogBuffer);
- return;
- }
- //If there was no existing assetId, then lets see if it already exists in a legacy file, like a materials.cs or materials.tscript
- //If it does, we'll just make our asset point to that instead of a new file
- Material* mat = MATMGR->getMaterialDefinitionByName(assetName);
- if (!mat)
- mat = MATMGR->getMaterialDefinitionByMapTo(assetName);
- if (!mat && assetItem->assetName != assetItem->cleanAssetName)
- {
- mat = MATMGR->getMaterialDefinitionByName(assetItem->cleanAssetName);
- if (!mat)
- mat = MATMGR->getMaterialDefinitionByMapTo(assetItem->cleanAssetName);
- }
- if(mat)
- {
- //We found a match, so just modify our asset item's info to point against it. This will create the asset definition, but otherwise leave the material definition as-is.
- assetItem->filePath = (Torque::Path)(mat->getFilename());
- }
- }
- else
- {
- if (activeImportConfig->AlwaysAddMaterialSuffix) //we only opt to force on the suffix if we're not obligating using the original material defs
- {
- assetItem->assetName += activeImportConfig->AddedMaterialSuffix;
- assetItem->cleanAssetName = assetItem->assetName;
- }
- if (activeImportConfig->PopulateMaterialMaps)
- {
- //If we're trying to populate the rest of our material maps, we need to go looking
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Attempting to Auto-Populate Material Maps");
- activityLog.push_back(importLogBuffer);
- AssetImportObject* matchedImageTypes[ImageAsset::ImageTypeCount] = { nullptr };
- String materialImageNoSuffix;
- for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
- {
- AssetImportObject* childAssetItem = assetItem->childAssetItems[i];
- if (childAssetItem->importStatus == AssetImportObject::Skipped || childAssetItem->assetType != String("ImageAsset"))
- continue;
- for (S32 t = 0; t < ImageAsset::ImageTypeCount; t++)
- {
- //If the imageType name and child asset image type match, check it off our list
- if (!dStricmp(ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t), childAssetItem->imageSuffixType.c_str()))
- {
- matchedImageTypes[t] = childAssetItem;
- if (t == ImageAsset::ImageTypes::Albedo)
- {
- String sufType;
- String suffix = parseImageSuffixes(childAssetItem->assetName, &sufType);
- String imageAssetName = childAssetItem->assetName;
- if (suffix.isEmpty())
- materialImageNoSuffix = imageAssetName;
- else
- materialImageNoSuffix = imageAssetName.erase(imageAssetName.length() - suffix.length(), suffix.length());//cache this for later as we may need it for file association lookups
- }
- }
- }
- }
- //Now that we've checked off any existingly matched image types, process through the unmatched to look for files that associate
- for (S32 t = 0; t < ImageAsset::ImageTypeCount; t++)
- {
- //This type wasn't found, so try and find a match based on suffix
- String suffixList;
- switch (t)
- {
- case ImageAsset::Albedo:
- suffixList = activeImportConfig->DiffuseTypeSuffixes;
- break;
- case ImageAsset::Normal:
- suffixList = activeImportConfig->NormalTypeSuffixes;
- break;
- case ImageAsset::ORMConfig:
- suffixList = activeImportConfig->PBRTypeSuffixes;
- break;
- case ImageAsset::Metalness:
- suffixList = activeImportConfig->MetalnessTypeSuffixes;
- break;
- case ImageAsset::AO:
- suffixList = activeImportConfig->AOTypeSuffixes;
- break;
- case ImageAsset::Roughness:
- suffixList = activeImportConfig->RoughnessTypeSuffixes;
- break;
- //TODO: Glow map lookup too
- }
- if (!matchedImageTypes[t])
- {
- U32 suffixCount = StringUnit::getUnitCount(suffixList.c_str(), ",;\t");
- for (U32 i = 0; i < suffixCount; i++)
- {
- //First, try checking based on the material's assetName for our patternbase
- String testPath = assetItem->filePath.getRootAndPath();
- testPath += "/" + assetItem->cleanAssetName + StringUnit::getUnit(suffixList.c_str(), i, ",;\t");
- String imagePath = AssetImporter::findImagePath(testPath);
- if (imagePath.isNotEmpty())
- {
- //got a match!
- AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
- newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t);
- matchedImageTypes[t] = newImageAssetObj;
- break;
- }
- else
- {
- if (materialImageNoSuffix.isNotEmpty())
- {
- testPath = assetItem->filePath.getRootAndPath();
- testPath += "/" + materialImageNoSuffix + StringUnit::getUnit(suffixList.c_str(), i, ",;\t");
- imagePath = AssetImporter::findImagePath(testPath);
- if (imagePath.isNotEmpty())
- {
- //got a match!
- AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
- newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t);
- matchedImageTypes[t] = newImageAssetObj;
- break;
- }
- }
- }
- }
- //If we're the abledo slot and after all that we didn't find anything, it probably is a suffixless image
- if (t == ImageAsset::Albedo && matchedImageTypes[t] == nullptr)
- {
- String testPath = assetItem->filePath.getRootAndPath() + "/" + assetItem->cleanAssetName;
- String imagePath = AssetImporter::findImagePath(testPath);
- if (imagePath.isNotEmpty())
- {
- //got a match!
- AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
- //In the event that the names match, we want to avoid duplications, so we'll go ahead and append a suffix onto our new image asset
- if (newImageAssetObj->assetName == assetItem->assetName)
- {
- newImageAssetObj->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
- newImageAssetObj->cleanAssetName = newImageAssetObj->assetName;
- }
- newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes::Albedo);
- matchedImageTypes[t] = newImageAssetObj;
- }
- }
- }
- else
- {
- //just a bit of cleanup and logical testing for matches
- //in the event we KNOW what the type is, but we don't have a suffix, such as a found image on a material lookup
- //that doesn't have a suffix, we assume it to be the albedo, so we'll just append the suffix to avoid collisions if
- //the name already matches our material name, similar to above logic
- if (matchedImageTypes[t]->assetName == assetItem->assetName)
- {
- matchedImageTypes[t]->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
- matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName;
- }
- }
- }
- /*for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
- {
- AssetImportObject* childAssetItem = assetItem->childAssetItems[i];
- if (childAssetItem->skip || childAssetItem->processed || childAssetItem->assetType != String("ImageAsset"))
- continue;
- if (childAssetItem->imageSuffixType == String("Albedo"))
- {
- assetItem->diffuseImageAsset = % childAssetItem;
- }
- }*/
- }
- }
-
- assetItem->importStatus = AssetImportObject::Processed;
- }
- 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();
- if (assetItem->shapeInfo == nullptr)
- {
- GuiTreeViewCtrl* shapeInfo = new GuiTreeViewCtrl();
- shapeInfo->registerObject();
- if (fileExt.compare("dae") == 0)
- {
- enumColladaForImport(filePath, shapeInfo, false);
- }
- else if (fileExt.compare("dts") == 0)
- {
- enumDTSForImport(filePath, shapeInfo);
- }
- 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;
- }
- if (activeImportConfig->AlwaysAddShapeSuffix)
- {
- assetItem->assetName += activeImportConfig->AddedShapeSuffix;
- assetItem->cleanAssetName = assetItem->assetName;
- }
- S32 meshCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_meshCount"), nullptr));
- S32 animCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_animCount"), nullptr));
- 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);
- AssetImportConfig* cachedConfig = new AssetImportConfig();;
- cachedConfig->registerObject();
- activeImportConfig->CopyTo(cachedConfig);
- if (!activeImportConfig->UseManualShapeConfigRules)
- {
- //Try and load a sis file if it exists for this format
- activeImportConfig->loadSISFile(assetItem->filePath);
- }
- 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 = "ShapeAnimationAsset";
- }
- }
- 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);
- }
- }
- //restore the cached version just in case we loaded a sis file
- cachedConfig->CopyTo(activeImportConfig);
- cachedConfig->deleteObject();
- assetItem->importStatus = AssetImportObject::Processed;
- }
- void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 materialItemId)
- {
- String matName = assetItem->shapeInfo->getItemText(materialItemId);
- String matAssetName = matName;
- if (matName == assetItem->assetName)
- {
- //So apparently we managed to name the material the same as the shape. So we'll tweak the name
- matAssetName += activeImportConfig->AddedMaterialSuffix;
- }
- //Do a check so we don't import materials that are on our ignore list
- if (activeImportConfig->IgnoreMaterials.isNotEmpty())
- {
- U32 ignoredMatNamesCount = StringUnit::getUnitCount(activeImportConfig->IgnoreMaterials, ",;\t");
- for (U32 i = 0; i < ignoredMatNamesCount; i++)
- {
- const char* ignoreMatName = StringUnit::getUnit(activeImportConfig->IgnoreMaterials, i, ",;\t");
- if (FindMatch::isMatch(ignoreMatName, matName.c_str(), false))
- {
- //If we have a match to one of our ignore names, just bail out here and skip the material wholesale
- return;
- }
- }
- }
- String materialItemValue = assetItem->shapeInfo->getItemValue(materialItemId);
- AssetImportObject* matAssetItem = nullptr;
- //If it happens to just be a color value instead of an image, we'll go ahead and skip doing any lookups
- //TODO: properly map the 'texture' color to the material that gets created
- if (materialItemValue.startsWith("Color:"))
- {
- matAssetItem = addImportingAsset("MaterialAsset", "", assetItem, matName);
- }
- else
- {
- Torque::Path filePath = materialItemValue;
- String fullFilePath = filePath.getFullFileName().c_str();
- String shapePathBase = assetItem->filePath.getRootAndPath();
- if (fullFilePath.isNotEmpty())
- {
- if (!Platform::isFile(fullFilePath.c_str()))
- {
- //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
-
- //trim (not found) if needbe
- fullFilePath = fullFilePath.replace(" (Not Found)", "");
- fullFilePath = fullFilePath.replace(" (not found)", "");
- String testFileName = shapePathBase + "/" + fullFilePath;
- if (Platform::isFile(testFileName.c_str()))
- {
- filePath = testFileName;
- }
- else
- {
- //Hmm, didn't find it. It could be that the in-model filename could be different by virtue of
- //image extension. Some files have source content files like psd's, but the mesh was exported to use
- //a dds or png, etc
- Torque::Path testFilePath = testFileName;
- String imgFileName = AssetImporter::findImagePath(testFilePath.getPath() + "/" + testFilePath.getFileName());
- if (imgFileName.isNotEmpty())
- filePath = imgFileName;
- }
- }
-
- matAssetItem = addImportingAsset("MaterialAsset", shapePathBase + "/", assetItem, matName);
- AssetImportObject* imageAssetItem = addImportingAsset("ImageAsset", filePath, matAssetItem, "");
- String suffixType;
- String suffix = parseImageSuffixes(imageAssetItem->assetName, &suffixType);
- if (suffix.isNotEmpty())
- {
- imageAssetItem->imageSuffixType = suffixType;
- }
- else
- {
- //we'll assume it's albedo
- imageAssetItem->imageSuffixType = "Albedo";
- }
- }
- else
- {
- matAssetItem = addImportingAsset("MaterialAsset", shapePathBase + "/" + matName, assetItem, matName);
- }
- }
- //In the event we modified the asset name(such as appending _Mat to avoid naming conflicts) update the name here
- //This preseves the 'clean asset name' which we can later use for lookups and the like as needed
- if (matAssetItem && matAssetName != matName)
- matAssetItem->assetName = matAssetName;
- }
- void AssetImporter::processSoundAsset(AssetImportObject* assetItem)
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Sound for Import: %s", assetItem->assetName.c_str());
- activityLog.push_back(importLogBuffer);
- if (activeImportConfig->AlwaysAddSoundSuffix)
- {
- assetItem->assetName += activeImportConfig->AddedSoundSuffix;
- assetItem->cleanAssetName = assetItem->assetName;
- }
- assetItem->importStatus = AssetImportObject::Processed;
- }
- //
- // 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->importStatus == AssetImportObject::Skipped || assetItem->importStatus == AssetImportObject::NotProcessed)
- return;
- if (checkAssetForCollision(assetItem))
- {
- importIssues = true;
- return;
- }
- if (!isReimport)
- {
- AssetQuery aQuery;
- U32 numAssetsFound = AssetDatabase.findAllAssets(&aQuery);
- for (U32 i = 0; i < numAssetsFound; i++)
- {
- StringTableEntry assetId = aQuery.mAssetList[i];
- ModuleDefinition* moduleDef = AssetDatabase.getAssetModuleDefinition(assetId);
- if ((moduleDef == NULL) || moduleDef->getModuleId() != StringTable->insert(targetModuleId.c_str()))
- continue;
- StringTableEntry assetName = AssetDatabase.getAssetName(assetId);
- if (assetName == StringTable->insert(assetItem->assetName.c_str()))
- {
- 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)
- {
- Vector<AssetImportObject*> itemList = importingAssets;
- if (assetItem != nullptr)
- itemList = assetItem->childAssetItems;
- for (U32 i = 0; i < itemList.size(); i++)
- {
- if (itemList[i]->importStatus == AssetImportObject::Skipped)
- continue;
- itemList[i]->status = "";
- itemList[i]->statusType = "";
- itemList[i]->statusInfo = "";
- //If it wasn't a match, try recusing on the children(if any)
- resetAssetValidationStatus(itemList[i]);
- }
- }
- bool AssetImporter::checkAssetForCollision(AssetImportObject* assetItemToCheck, AssetImportObject* assetItem)
- {
- bool results = false;
- Vector<AssetImportObject*> itemList = importingAssets;
- if (assetItem != nullptr)
- itemList = assetItem->childAssetItems;
- for (U32 i = 0; i < itemList.size(); i++)
- {
- AssetImportObject* importingAsset = itemList[i];
- if (importingAsset->importStatus == AssetImportObject::Skipped)
- continue;
- if ((assetItemToCheck->assetName.compare(importingAsset->assetName) == 0) && (assetItemToCheck->getId() != importingAsset->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 \"" + importingAsset->assetName + "\" of the type \"" + importingAsset->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(),
- importingAsset->assetName.c_str(), importingAsset->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, importingAsset);
- 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->DuplicateAutoResolution == String("AutoPrune"))
- {
- //delete the item
- if (assetItem->parentAssetItem == nullptr)
- {
- //if there's no parent, just delete
- deleteImportingAsset(assetItem);
- }
- else
- {
- //otherwise, we'll likely want to retain our dependency for our parent
- assetItem->importStatus = AssetImportObject::UseForDependencies;
- }
- //log it's deletion
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was autopruned 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->DuplicateAutoResolution == String("AutoRename"))
- {
- //Set trailing number
- String renamedAssetName = assetItem->assetName;
- String renamedAssetId = assetItem->moduleName + ":" + renamedAssetName;
- String addedSuffix;
- if (assetItem->assetType == String("ShapeAsset"))
- addedSuffix = activeImportConfig->AddedShapeSuffix;
- else if (assetItem->assetType == String("MaterialAsset"))
- addedSuffix = activeImportConfig->AddedMaterialSuffix;
- else if (assetItem->assetType == String("ImageAsset"))
- addedSuffix = activeImportConfig->AddedImageSuffix;
- else if (assetItem->assetType == String("SoundAsset"))
- addedSuffix = activeImportConfig->AddedSoundSuffix;
- //do the suffix if it isn't already on it
- if (!renamedAssetName.endsWith(addedSuffix.c_str()))
- {
- renamedAssetName += addedSuffix;
- renamedAssetId = assetItem->moduleName + ":" + renamedAssetName;
- assetItem->assetName = renamedAssetName;
- }
- //if still conflicted
- //add the directory prefix
- if (AssetDatabase.isDeclaredAsset(renamedAssetId.c_str()))
- {
- renamedAssetName = getFolderPrefixedName(assetItem);
- renamedAssetId = assetItem->moduleName + ":" + renamedAssetName;
- assetItem->assetName = renamedAssetName;
- }
- bool appendedNumber = false;
- U32 uniqueNumber = 0;
- while (AssetDatabase.isDeclaredAsset(renamedAssetId.c_str()))
- {
- uniqueNumber++;
- renamedAssetId = assetItem->moduleName + ":" + renamedAssetName + String::ToString(uniqueNumber);
- appendedNumber = true;
- }
- if (appendedNumber)
- {
- renamedAssetName += String::ToString(uniqueNumber);
- }
- //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 (activeImportConfig->DuplicateAutoResolution == String("UseExisting"))
- {
- }
- else if (activeImportConfig->DuplicateAutoResolution == String("FolderPrefix"))
- {
- String renamedAssetName = getFolderPrefixedName(assetItem);
- //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?
- }
- }
- void AssetImporter::resetImportConfig()
- {
- //use a default import config
- if (activeImportConfig == nullptr)
- {
- activeImportConfig = new AssetImportConfig();
- activeImportConfig->registerObject();
- }
- Settings* editorSettings;
- //See if we can get our editor settings
- if (Sim::findObject("EditorSettings", editorSettings))
- {
- String defaultImportConfig = editorSettings->value("Assets/AssetImporDefaultConfig");
- //If we found it, grab the import configs
- Settings* importConfigs;
- if (Sim::findObject("AssetImportSettings", importConfigs))
- {
- //Now load the editor setting-deigned config!
- activeImportConfig->loadImportConfig(importConfigs, defaultImportConfig.c_str());
- }
- }
- }
- //
- // Importing
- //
- StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath, String typeHint)
- {
- //Just in case we're reusing the same importer object from another import session, nuke any existing files
- resetImportSession(true);
- 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);
- dumpActivityLog();
- 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);
- dumpActivityLog();
- 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 = AssetImporter::getModuleFromPath(filePath);
- if (targetModuleDef == nullptr)
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is not in a valid module folder.", filePath.getFullPath().c_str());
- activityLog.push_back(importLogBuffer);
- dumpActivityLog();
- return StringTable->EmptyString();
- }
- else
- {
- targetModuleId = targetModuleDef->getModuleId();
- }
- //set our path
- targetPath = filePath.getPath();
- resetImportConfig();
- AssetImportObject* assetItem = addImportingAsset(assetType, filePath, nullptr, "");
- 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();
- }
- dumpActivityLog();
- 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;
- }
- Vector<AssetImportObject*> itemList = importingAssets;
- if (assetItem != nullptr)
- itemList = assetItem->childAssetItems;
- for (U32 i = 0; i < itemList.size(); i++)
- {
- AssetImportObject* item = itemList[i];
- if (!item->canImport())
- continue;
- Torque::Path assetPath;
- if (item->assetType == String("ImageAsset"))
- {
- assetPath = importImageAsset(item);
- }
- else if (item->assetType == String("ShapeAsset"))
- {
- assetPath = importShapeAsset(item);
- }
- else if (item->assetType == String("SoundAsset"))
- {
- assetPath = importSoundAsset(item);
- }
- else if (item->assetType == String("MaterialAsset"))
- {
- assetPath = importMaterialAsset(item);
- }
- else
- {
- finalImportedAssetPath = String::EmptyString;
- String processCommand = "import";
- processCommand += item->assetType;
- if (isMethod(processCommand.c_str()))
- {
- Con::executef(this, processCommand.c_str(), item);
- assetPath = finalImportedAssetPath;
- }
- }
- /*else if (importingAssets[i]->assetType == String("ShapeAnimationAsset"))
- assetPath = ShapeAnimationAsset::importAsset(importingAssets[i]);*/
- if (assetPath.isEmpty() && item->assetType != String("MaterialAsset"))
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Import attempt of %s failed, so skipping asset.", item->assetName.c_str());
- activityLog.push_back(importLogBuffer);
- continue;
- }
- else
- {
- //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
- {
- //Any special-case post-reg stuff here
- if (item->assetType == String("ShapeAsset"))
- {
- String assetIdStr = item->moduleName + ":" + item->assetName;
- StringTableEntry assetId = StringTable->insert(assetIdStr.c_str());
- //forcefully update it's shape constructor
- TSShapeConstructor* tss = TSShapeConstructor::findShapeConstructorByAssetId(assetId);
- if(tss)
- tss->setShapeAssetId(assetId);
- }
- }
- }
- else
- {
- String assetId = item->moduleName + ":" + item->assetName;
- bool refreshSuccess = AssetDatabase.refreshAsset(assetId.c_str());
- if (!refreshSuccess)
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to refresh reimporting asset %s.", item->assetName.c_str());
- activityLog.push_back(importLogBuffer);
- }
- }
- }
- //Mark us as successfully imported
- item->importStatus = AssetImportObject::Imported;
- //recurse if needed
- importAssets(item);
- }
- }
- //
- // 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());
- //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
- //file path for reimporting support later
- if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile))
- {
- newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
- }
- if (assetItem->typeHint != String::EmptyString)
- {
- newAsset->setImageType(ImageAsset::getImageTypeFromName(StringTable->insert(assetItem->typeHint.c_str())));
- }
- else
- {
- 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 = !String::compare(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 + "." TORQUE_SCRIPT_EXTENSION;
- 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);
- newAsset->setDataField(StringTable->insert("materialDefinitionName"), nullptr, assetName);
-
- //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->canImport() && childItem->importStatus != AssetImportObject::UseForDependencies) || childItem->assetType.compare("ImageAsset") != 0)
- continue;
- char dependencyFieldName[64];
- dSprintf(dependencyFieldName, 64, "imageMap%i", dependencySlotId);
- char dependencyFieldDef[512];
- dSprintf(dependencyFieldDef, 512, "%s=%s:%s", ASSET_ID_SIGNATURE, 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 ORMConfig file if we're flagged to and have valid image maps
- if (activeImportConfig->CreateORMConfig)
- {
- AssetImportObject* ormMap = 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->canImport() || childItem->assetType.compare("ImageAsset") != 0)
- continue;
- if (childItem->imageSuffixType.compare("ORMConfig") == 0)
- ormMap = 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 (ormMap != nullptr && ormMap->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, ormMap->filePath.getFullPath(), &GFXTexturePersistentProfile);
- }
- }
- }
- FileObject* file = new FileObject();
- file->registerObject();
- if (activeImportConfig->UseExistingMaterials && Platform::isFile(qualifiedFromFile))
- {
- //Now write the script file containing our material out
- //There's 2 ways to do this. If we're in-place importing an existing asset, we can see if the definition existed already, like in an old
- //materials.tscript file. if it does, we can just find the object by name, and save it out to our new file
- //If not, we'll just generate one
- Material* existingMat = MATMGR->getMaterialDefinitionByName(assetName);
- //It's also possible that, for legacy models, the material hooks in via the material's mapTo field, and the material name is something completely different
- //So we'll check for that as well if we didn't find it by name up above
- if (existingMat == nullptr)
- existingMat = MATMGR->getMaterialDefinitionByMapTo(assetName);
- if (existingMat == nullptr && assetItem->assetName != assetItem->cleanAssetName)
- {
- existingMat = MATMGR->getMaterialDefinitionByName(assetItem->cleanAssetName);
- if (existingMat == nullptr)
- existingMat = MATMGR->getMaterialDefinitionByMapTo(assetItem->cleanAssetName);
- }
- if (existingMat)
- {
- PersistenceManager* persistMgr;
- if (Sim::findObject("ImageAssetValidator", persistMgr))
- {
- for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
- {
- AssetImportObject* childItem = assetItem->childAssetItems[i];
- if (childItem->canImport() || childItem->assetType.compare("ImageAsset") != 0)
- continue;
- String path = childItem->filePath.getFullFileName();
- String mapFieldName = "";
- String assetFieldName = "";
- ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType);
- if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty())
- {
- mapFieldName = "DiffuseMap";
- }
- else if (imageType == ImageAsset::ImageTypes::Normal)
- {
- mapFieldName = "NormalMap";
- }
- else if (imageType == ImageAsset::ImageTypes::ORMConfig)
- {
- mapFieldName = "ORMConfig";
- }
- else if (imageType == ImageAsset::ImageTypes::Metalness)
- {
- mapFieldName = "MetalnessMap";
- }
- else if (imageType == ImageAsset::ImageTypes::AO)
- {
- mapFieldName = "AOMap";
- }
- else if (imageType == ImageAsset::ImageTypes::Roughness)
- {
- mapFieldName = "RoughnessMap";
- }
- assetFieldName = mapFieldName + "Asset[0]";
- mapFieldName += "[0]";
- //If there's already an existing image map file on the material definition in this slot, don't override it
- if (!path.isEmpty())
- existingMat->writeField(mapFieldName.c_str(), path.c_str());
- String targetAsset = targetModuleId + ":" + childItem->assetName;
- existingMat->writeField(assetFieldName.c_str(), targetAsset.c_str());
- }
- persistMgr->setDirty(existingMat);
- }
- else
- {
- Con::errorf("ImageAssetValidator not found!");
- }
- }
- else
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Failed to find original material definition %s!", assetName);
- activityLog.push_back(importLogBuffer);
- return tamlPath;
- }
- }
- else 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);
- bool hasRoughness = false;
- for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
- {
- AssetImportObject* childItem = assetItem->childAssetItems[i];
- if ((!childItem->canImport() && childItem->importStatus != AssetImportObject::UseForDependencies) || childItem->assetType.compare("ImageAsset") != 0)
- continue;
- String mapFieldName = "";
- String assetFieldName = "";
- ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType);
- if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty())
- {
- mapFieldName = "DiffuseMap";
- }
- else if (imageType == ImageAsset::ImageTypes::Normal)
- {
- mapFieldName = "NormalMap";
- }
- else if (imageType == ImageAsset::ImageTypes::ORMConfig)
- {
- mapFieldName = "ORMConfigMap";
- }
- else if (imageType == ImageAsset::ImageTypes::Metalness)
- {
- mapFieldName = "MetalnessMap";
- }
- else if (imageType == ImageAsset::ImageTypes::AO)
- {
- mapFieldName = "AOMap";
- }
- else if (imageType == ImageAsset::ImageTypes::Roughness)
- {
- mapFieldName = "RoughnessMap";
- hasRoughness = true;
- }
- assetFieldName = mapFieldName + "Asset";
- mapFieldName += "[0]";
- //String path = childItem->filePath.getFullFileName();
- //dSprintf(lineBuffer, 1024, " %s = \"%s\";", mapFieldName.c_str(), path.c_str());
- //file->writeLine((U8*)lineBuffer);
- dSprintf(lineBuffer, 1024, " %s = \"%s:%s\";", assetFieldName.c_str(), targetModuleId.c_str(), childItem->assetName.c_str());
- file->writeLine((U8*)lineBuffer);
- }
- if (hasRoughness)
- {
- file->writeLine((U8*)" invertSmoothness = true;");
-
- }
- 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 constructorFileName = assetItem->filePath.getFileName() + "." TORQUE_SCRIPT_EXTENSION;
- String assetPath = targetPath + "/" + shapeFileName;
- String constructorPath = targetPath + "/" + constructorFileName;
- String tamlPath = targetPath + "/" + assetName + ".asset.taml";
- String originalPath = assetItem->filePath.getFullPath().c_str();
- String originalConstructorPath = assetItem->filePath.getPath() + "/" + constructorFileName;
- 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->setShapeConstructorFile(constructorFileName.c_str());
- AssetImportConfig* cachedConfig = new AssetImportConfig();
- cachedConfig->registerObject();
- activeImportConfig->CopyTo(cachedConfig);
- if (!activeImportConfig->UseManualShapeConfigRules)
- {
- //Try and load a sis file if it exists for this format
- activeImportConfig->loadSISFile(assetItem->filePath);
- }
- //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
- //file path for reimporting support later
- if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile))
- {
- 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->canImport() && childItem->importStatus != AssetImportObject::UseForDependencies)
- continue;
- if (childItem->assetType.compare("MaterialAsset") == 0)
- {
- char dependencyFieldName[64];
- dSprintf(dependencyFieldName, 64, "materialSlot%i", dependencySlotId);
- char dependencyFieldDef[512];
- dSprintf(dependencyFieldDef, 512, "%s=%s:%s", ASSET_ID_SIGNATURE, 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, "%s=%s:%s", ASSET_ID_SIGNATURE, 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 = !String::compare(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)
- {
- if (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);
- }
- }
- }
- else
- {
- //We're doing an in-place import, so double check we've already got a constructor file in the expected spot
- if (Platform::isFile(qualifiedFromCSFile))
- {
- //Yup, found it, we're good to go
- makeNewConstructor = false;
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Existing TSShape Constructor file %s found", qualifiedFromCSFile);
- activityLog.push_back(importLogBuffer);
- }
- else
- {
- //Didn't work, but it's possible it's using the old .cs extension when our extension variable is set to something else, so check that one as well just to be sure
- Torque::Path constrFilePath = qualifiedFromCSFile;
- constrFilePath.setExtension("cs");
- if (Platform::isFile(constrFilePath.getFullPath().c_str()))
- {
- //Yup, found it, we're good to go
- makeNewConstructor = false;
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Existing TSShape Constructor file %s found", constrFilePath.getFullPath().c_str());
- 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::findShapeConstructorByFilename(Torque::Path(qualifiedToFile).getFullPath());
- if (constructor == nullptr)
- {
- String fullAssetName = assetItem->moduleName + ":" + assetItem->assetName;
- constructor = new TSShapeConstructor(StringTable->insert(fullAssetName.c_str()));
- String constructorName = assetItem->filePath.getFileName() + assetItem->filePath.getExtension().substr(0, 3);
- constructorName.replace(" ", "_");
- 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, ",;\t");
- for (U32 i = 0; i < ignoredMatNamesCount; i++)
- {
- if (i == 0)
- neverImportMats = StringUnit::getUnit(activeImportConfig->IgnoreMaterials, i, ",;\t");
- else
- neverImportMats += String("\t") + StringUnit::getUnit(activeImportConfig->IgnoreMaterials, i, ",;\t");
- }
- }
- if (activeImportConfig->DoUpAxisOverride)
- {
- S32 upAxis = domUpAxisType::UPAXISTYPE_Z_UP;
- 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 = ColladaUtils::ImportOptions::eLodType::TrailingNumber;
- 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->AlwaysImportedNodes;
- constructor->mOptions.neverImport = activeImportConfig->AlwaysIgnoreNodes;
- constructor->mOptions.alwaysImportMesh = activeImportConfig->AlwaysImportMeshes;
- constructor->mOptions.neverImportMesh = activeImportConfig->AlwaysIgnoreMeshes;
- 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;
- PersistenceManager* constructorPersist = new PersistenceManager();
- constructorPersist->registerObject();
- constructorPersist->setDirty(constructor, qualifiedToCSFile);
- if (!constructorPersist->saveDirtyObject(constructor))
- {
- 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);
- }
- constructorPersist->destroySelf();
- }
- //restore the cached version just in case we loaded a sis file
- cachedConfig->CopyTo(activeImportConfig);
- cachedConfig->deleteObject();
- return tamlPath;
- }
- Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem)
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Sound Asset: %s", assetItem->assetName.c_str());
- activityLog.push_back(importLogBuffer);
- SoundAsset* newAsset = new SoundAsset();
- 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->setSoundFile(imageFileName.c_str());
- //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
- //file path for reimporting support later
- if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile))
- {
- newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
- }
- 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 = !String::compare(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::importShapeAnimationAsset(AssetImportObject* assetItem)
- {
- dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Shape Animation Asset: %s", assetItem->assetName.c_str());
- activityLog.push_back(importLogBuffer);
- ShapeAnimationAsset* newAsset = new ShapeAnimationAsset();
- 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->setAnimationFile(imageFileName.c_str());
- //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
- //file path for reimporting support later
- if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile))
- {
- newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
- }
- 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 = !String::compare(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;
- }
|