From 5c8d8fab005a15a071002d91b0063ebe1750d725 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 10 Apr 2022 01:40:15 -0500 Subject: [PATCH 1/2] Changes behavior with suffix appending of asset importer so it doesn't contaminate the original "clean" name, which is used for setting the mapTo value of material definitions Also adds a sanity check when applying the type suffix to see if it's already there to avoid needless doubleups Fixes offsetting/positioning behavior on icon buttons to actually respect the icon position variable Adds sanity checks to ensure we're not trying to utilize a in-process-of-deleting decoy dummy Fixes handling of sliders in option menus to properly store and test unapplied values Fixes handling of display device setting to properly store and test unapplied values Adds additional logic to creation of shape and material asset previews to attempt to force-load dependencies to improve likelihood that they'll actually be loaded when we go to generate the preview. Temp disables creating cubemap 'assets' via the RMB context menu in the AB --- Engine/source/T3D/assets/assetImporter.cpp | 30 +++++++-------- Engine/source/console/fileSystemFunctions.cpp | 16 ++++++++ .../source/gui/buttons/guiIconButtonCtrl.cpp | 37 ++++++++++++++++--- Engine/source/gui/controls/guiDecoyCtrl.cpp | 6 ++- .../game/data/UI/guis/optionsMenu.tscript | 29 +++++++++++---- .../scripts/assetTypes/material.tscript | 9 ++++- .../scripts/assetTypes/shape.tscript | 11 +++++- .../assetBrowser/scripts/popupMenus.tscript | 1 + 8 files changed, 108 insertions(+), 31 deletions(-) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index d0b498d26..de19bc983 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -1633,7 +1633,7 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem) { String diffuseToken = StringUnit::getUnit(activeImportConfig->DiffuseTypeSuffixes, 0, ",;\t"); assetItem->assetName = assetItem->assetName + diffuseToken; - assetItem->cleanAssetName = assetItem->assetName; + //assetItem->cleanAssetName = assetItem->assetName; } else { @@ -1642,7 +1642,7 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem) if ((materialAsset && materialAsset->assetName.compare(assetItem->assetName) == 0) || activeImportConfig->AlwaysAddImageSuffix) { assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix; - assetItem->cleanAssetName = assetItem->assetName; + //assetItem->cleanAssetName = assetItem->assetName; } } @@ -1673,8 +1673,8 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem) if(assetItem->assetName == assetItem->cleanAssetName && activeImportConfig->AlwaysAddImageSuffix) { - assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix; - assetItem->cleanAssetName = assetItem->assetName; + if (!assetItem->assetName.endsWith(activeImportConfig->AddedImageSuffix.c_str())) + assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix; } assetItem->importStatus = AssetImportObject::Processed; @@ -1752,8 +1752,8 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem) { 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(!assetItem->assetName.endsWith(activeImportConfig->AddedMaterialSuffix.c_str())) + assetItem->assetName += activeImportConfig->AddedMaterialSuffix; } if (activeImportConfig->PopulateMaterialMaps) @@ -1936,7 +1936,7 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem) if (newImageAssetObj->assetName == assetItem->assetName) { newImageAssetObj->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t"); - newImageAssetObj->cleanAssetName = newImageAssetObj->assetName; + //newImageAssetObj->cleanAssetName = newImageAssetObj->assetName; } newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes::Albedo); @@ -1954,7 +1954,7 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem) if (matchedImageTypes[t]->assetName == assetItem->assetName) { matchedImageTypes[t]->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t"); - matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName; + //matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName; } } } @@ -2000,8 +2000,8 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem) if (activeImportConfig->AlwaysAddShapeSuffix) { - assetItem->assetName += activeImportConfig->AddedShapeSuffix; - assetItem->cleanAssetName = assetItem->assetName; + if(!assetItem->assetName.endsWith(activeImportConfig->AddedShapeSuffix.c_str())) + assetItem->assetName += activeImportConfig->AddedShapeSuffix; } S32 meshCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_meshCount"), nullptr)); @@ -2094,8 +2094,8 @@ void AssetImporter::processShapeAnimationAsset(AssetImportObject* assetItem) if (activeImportConfig->AlwaysAddShapeAnimationSuffix) { - assetItem->assetName += activeImportConfig->AddedShapeAnimationSuffix; - assetItem->cleanAssetName = assetItem->assetName; + if (!assetItem->assetName.endsWith(activeImportConfig->AddedShapeAnimationSuffix.c_str())) + assetItem->assetName += activeImportConfig->AddedShapeAnimationSuffix; } S32 animCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_animCount"), nullptr)); @@ -2237,8 +2237,8 @@ void AssetImporter::processSoundAsset(AssetImportObject* assetItem) if (activeImportConfig->AlwaysAddSoundSuffix) { - assetItem->assetName += activeImportConfig->AddedSoundSuffix; - assetItem->cleanAssetName = assetItem->assetName; + if (!assetItem->assetName.endsWith(activeImportConfig->AddedSoundSuffix.c_str())) + assetItem->assetName += activeImportConfig->AddedSoundSuffix; } assetItem->importStatus = AssetImportObject::Processed; @@ -2916,7 +2916,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) { Material* newMat = new Material(); newMat->registerObject(assetName); - newMat->mMapTo = assetName; + newMat->mMapTo = assetItem->cleanAssetName; bool hasRoughness = false; for (U32 i = 0; i < assetItem->childAssetItems.size(); i++) diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index 010147af2..3f43e962d 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -892,4 +892,20 @@ DefineEngineFunction( createPath, bool, ( const char* path ),, return Platform::createPath( pathName ); } +DefineEngineFunction(deleteDirectory, bool, (const char* path), , + "@brief Delete a directory from the hard drive\n\n" + + "@param path Name and path of the folder to delete\n" + "@note THERE IS NO RECOVERY FROM THIS. Deleted files are gone for good.\n" + "@return True if file was successfully deleted\n" + "@ingroup FileSystem") +{ + static char fileName[1024]; + static char sandboxFileName[1024]; + + Con::expandScriptFilename(fileName, sizeof(fileName), path); + Platform::makeFullPathName(fileName, sandboxFileName, sizeof(sandboxFileName)); + + return Platform::deleteDirectory(sandboxFileName); +} #endif // TORQUE_TOOLS diff --git a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp index 57f9f9123..32b5be36b 100644 --- a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp @@ -240,10 +240,15 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) { // If there is a bitmap array then render using it. // Otherwise use a standard fill. - if(mProfile->mUseBitmapArray && mProfile->mBitmapArrayRects.size()) + if (mProfile->mUseBitmapArray && mProfile->mBitmapArrayRects.size()) + { renderBitmapArray(boundsRect, stateMouseOver); + } else - renderSlightlyRaisedBox(boundsRect, mProfile); + { + drawer->drawRectFill(boundsRect, mProfile->mFillColorHL); + drawer->drawRect(boundsRect, mProfile->mBorderColorHL); + } } else { @@ -258,8 +263,16 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) } else { - drawer->drawRectFill(boundsRect, mProfile->mFillColorNA); - drawer->drawRect(boundsRect, mProfile->mBorderColorNA); + if (mActive) + { + drawer->drawRectFill(boundsRect, mProfile->mFillColor); + drawer->drawRect(boundsRect, mProfile->mBorderColor); + } + else + { + drawer->drawRectFill(boundsRect, mProfile->mFillColorNA); + drawer->drawRect(boundsRect, mProfile->mBorderColorNA); + } } } @@ -302,7 +315,7 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) } else { - iconRect.set( offset + mButtonMargin, getExtent() - (mButtonMargin * 2) ); + iconRect.set( offset + mButtonMargin, getExtent() - (Point2I(mAbs(mButtonMargin.x), mAbs(mButtonMargin.y)) * 2) ); if ( mMakeIconSquare ) { @@ -313,6 +326,20 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) iconRect.extent.x = iconRect.extent.y; } + if (mIconLocation == IconLocRight) + { + iconRect.point.x = (offset.x + getWidth()) - iconRect.extent.x + mButtonMargin.x; + } + else if (mIconLocation == IconLocLeft) + { + //default state presumes left positioning + } + else if (mIconLocation == IconLocCenter) + { + iconRect.point.x = offset.x + (getWidth() / 2) - (iconRect.extent.x / 2) + mButtonMargin.x; + iconRect.point.y = offset.y + (getHeight() / 2) - (iconRect.extent.y / 2) + mButtonMargin.y; + } + drawer->drawBitmapStretch( mBitmap, iconRect ); } } diff --git a/Engine/source/gui/controls/guiDecoyCtrl.cpp b/Engine/source/gui/controls/guiDecoyCtrl.cpp index 61b489995..54ca105ae 100644 --- a/Engine/source/gui/controls/guiDecoyCtrl.cpp +++ b/Engine/source/gui/controls/guiDecoyCtrl.cpp @@ -146,12 +146,14 @@ void GuiDecoyCtrl::onMouseMove(const GuiEvent &event) GuiControl *tempControl = parent->findHitControl(localPoint); //the decoy control has the responsibility of keeping track of the decoyed controls status - if(mMouseOverDecoy == false && mDecoyReference != NULL) + if(mMouseOverDecoy == false && mDecoyReference != NULL && + !mDecoyReference->isDeleted() && !mDecoyReference->isRemoved()) { tempControl->onMouseEnter(event); mMouseOverDecoy = true; } - else if(tempControl != mDecoyReference && mDecoyReference != NULL) + else if(tempControl != mDecoyReference && mDecoyReference != NULL && + !mDecoyReference->isDeleted() && !mDecoyReference->isRemoved()) { mDecoyReference->onMouseLeave(event); mMouseOverDecoy = false; diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index 2dd1d7f10..aa343f81f 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -200,7 +200,7 @@ function OptionsMenu::apply(%this) //for updates if ( %targetVar $= "$pref::Video::displayDevice" ) { - MessageBoxOK( "Change requires restart", "Please restart the game for a display device change to take effect." ); + schedule(32, 0, "MessageBoxOK", "Change requires restart", "Please restart the game for a display device change to take effect."); } else if(startsWith(%targetVar, "$pref::PostFX::")) { @@ -349,11 +349,6 @@ function populateDisplaySettingsList() OptionName.setText(""); OptionDescription.setText(""); - //First, lets double-check the active device is accurate. Sometimes the default value in our prefs doesn't match the active one - %displayDevice = getDisplayDeviceType(); - if($changingDisplayDevice !$= "") - %displayDevice = $changingDisplayDevice; - %apiList = ""; %apiCount = GFXInit::getAdapterCount(); %apiIdx = 0; @@ -374,7 +369,11 @@ function populateDisplaySettingsList() trim(%apiList); - OptionsMenuSettingsList.addOptionRow("Display API", "$pref::Video::DisplayAPI", %apiList, false, "", true, "The display API used for rendering.", %displayDevice); + %displayDevice = OptionsMenu.getOptionVariableValue("$pref::Video::displayDevice"); + if(%displayDevice $= "") + %displayDevice = getDisplayDeviceType(); + + OptionsMenuSettingsList.addOptionRow("Display API", "$pref::Video::displayDevice", %apiList, false, "", true, "The display API used for rendering.", %displayDevice); %numDevices = Canvas.getMonitorCount(); %devicesList = ""; @@ -977,6 +976,8 @@ function MenuOptionsButton::onChange(%this) OptionName.setText(%optionName); OptionDescription.setText(%tooltipText); + if(%optionMode == 0) + { %currentValue = %this.getCurrentOption(); if(%currentValue !$= "") { @@ -995,6 +996,20 @@ function MenuOptionsButton::onChange(%this) } else OptionsMenu.unappliedChanges.setValue("\"" @ %saveReadyValue @ "\"", %prefIndex); + } + } + else if(%optionMode == 1) + { + %currentValue = %this.getValue(); + + %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetVar); + if(%prefIndex == -1) + { + echo("Setting UnappliedChanges via add: key:" @ %targetVar @", value: " @ %currentValue); + OptionsMenu.unappliedChanges.add(%targetVar, "\"" @ %currentValue @ "\"" ); + } + else + OptionsMenu.unappliedChanges.setValue("\"" @ %currentValue @ "\"", %prefIndex); } //Update the UI in case there's responsive logic diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index debcaffd8..d6d48819c 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -462,10 +462,17 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData, if(isObject(%assetDef.materialDefinitionName)) { + //real fast, we'll be 100% sure that the image resource we need is loaded + %diffuseMapAssetId = %assetDef.materialDefinitionName.getDiffuseMapAsset(0); + if(AssetDatabase.isDeclaredAsset(%diffuseMapAssetId)) + { + %diffuseMapAsset = AssetDatabase.acquireAsset(%diffuseMapAssetId); + AssetDatabase.releaseAsset(%diffuseMapAssetId); + } %previewShapeDef = AssetDatabase.acquireAsset("ToolsModule:previewSphereShape"); %generatedFilePath = %previewShapeDef.generateCachedPreviewImage(256, %assetDef.materialDefinitionName); - pathCopy(%generatedFilePath, %previewFilePath); + pathCopy(%generatedFilePath, %previewFilePath, false); fileDelete(%generatedFilePath); if(!AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript index 250e7c6ac..c70750e90 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript @@ -290,12 +290,21 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData, %f { displayEditorLoadingGui("Generating Shape Asset Preview..."); + //real fast, we'll be 100% sure that the image resource we need is loaded + + %matSlot0AssetId = %assetDef.materialSlot0; + if(AssetDatabase.isDeclaredAsset(%matSlot0AssetId)) + { + %matAsset = AssetDatabase.acquireAsset(%matSlot0AssetId); + AssetDatabase.releaseAsset(%matSlot0AssetId); + } + //This is slightly hacky, but we're going to utilize the imposter/last detail system //to generate our previews for us and then clean up the unneeded bits %filePath = %assetDef.generateCachedPreviewImage(); - pathCopy(%filePath, %previewFilePath); + pathCopy(%filePath, %previewFilePath, false); fileDelete(%filePath); //cleanup if(!AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript index 808649d86..27d198e8e 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript @@ -237,6 +237,7 @@ function AssetBrowser::buildPopupMenus(%this) AddNewArtAssetPopup.enableItem(7, false); //shape animation AddNewArtAssetPopup.enableItem(13, false); //sound asset AddNewArtAssetPopup.enableItem(15, false); //particle effect + AddNewArtAssetPopup.enableItem(17, false); //cubemap if( !isObject( EditFolderPopup ) ) { From 1c7c32baa6c271dc35106ca3988f7e71d19c6ad5 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 10 Apr 2022 19:41:37 -0500 Subject: [PATCH 2/2] Separates out acquireAsset call for importing assets until after all assets have been imported, then runs it as a post step to ensure all assets are properly loaded before they're used --- Engine/source/T3D/assets/MaterialAsset.cpp | 5 --- Engine/source/T3D/assets/assetImporter.cpp | 37 ++++++++++++++++--- Engine/source/T3D/assets/assetImporter.h | 6 +++ .../T3D/assets/assetImporter_ScriptBinding.h | 4 +- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index 77b22cc24..6153cd3e8 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -174,11 +174,6 @@ void MaterialAsset::initializeAsset() return; } - if (mMatDefinitionName == StringTable->insert("DetailBlue")) - { - bool asdfsd = true; - } - if (size() != 0 && mScriptPath == StringTable->EmptyString()) { mLoadedState = EmbeddedDefinition; diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index de19bc983..865af276f 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -1727,7 +1727,8 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem) //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); + Material* mat; + Sim::findObject(assetName, mat); if (!mat) mat = MATMGR->getMaterialDefinitionByMapTo(assetName); @@ -2618,6 +2619,8 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath, String typ else { importAssets(); + + acquireAssets(); } dumpActivityLog(); @@ -2729,10 +2732,6 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) tss->setShapeAssetId(assetId); } } - - //Go ahead and force the asset to load now just to kick it for immediate use - AssetBase* assetDef = AssetDatabase.acquireAsset(assetId); - AssetDatabase.releaseAsset(assetId); } else { @@ -2757,6 +2756,34 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) dumpActivityLog(); } +void AssetImporter::acquireAssets(AssetImportObject* assetItem) +{ + Vector itemList = importingAssets; + if (assetItem != nullptr) + itemList = assetItem->childAssetItems; + + for (U32 i = 0; i < itemList.size(); i++) + { + AssetImportObject* item = itemList[i]; + if (item->importStatus == AssetImportObject::Skipped || + item->importStatus == AssetImportObject::NotProcessed || + item->importStatus == AssetImportObject::Error) + continue; + + //recurse if needed, we want to process child items first for dependency reasons + acquireAssets(item); + + //Go ahead and force the asset to load now just to kick it for immediate use + String assetId = item->moduleName + ":" + item->assetName; + + if (AssetDatabase.isDeclaredAsset(assetId)) + { + AssetBase* assetDef = AssetDatabase.acquireAsset(assetId); + AssetDatabase.releaseAsset(assetId); + } + } +} + // // Type-specific import logic // diff --git a/Engine/source/T3D/assets/assetImporter.h b/Engine/source/T3D/assets/assetImporter.h index 4e2fc53aa..6e77ef965 100644 --- a/Engine/source/T3D/assets/assetImporter.h +++ b/Engine/source/T3D/assets/assetImporter.h @@ -914,6 +914,12 @@ public: /// Torque::Path importShapeAnimationAsset(AssetImportObject* assetItem); + /// + /// Iterates over all the items in the current session and acquires them, which jumpstarts the loading/init'ng process on them, making the available for use immediately + /// @param assetItem, if null, will loop over and recurse the main import asset items, if a specific AssetImportObject is passed in, it will recurse it's children + /// + void acquireAssets(AssetImportObject* assetItem = nullptr); + // /// /// Gets the currently active import configuration diff --git a/Engine/source/T3D/assets/assetImporter_ScriptBinding.h b/Engine/source/T3D/assets/assetImporter_ScriptBinding.h index aa50c82de..a9a94672b 100644 --- a/Engine/source/T3D/assets/assetImporter_ScriptBinding.h +++ b/Engine/source/T3D/assets/assetImporter_ScriptBinding.h @@ -92,7 +92,9 @@ DefineEngineMethod(AssetImporter, resolveAssetItemIssues, void, (AssetImportObje DefineEngineMethod(AssetImporter, importAssets, void, (),, "Runs the actual import action on the items.") { - return object->importAssets(); + object->importAssets(); + + object->acquireAssets(); } DefineEngineMethod(AssetImporter, getAssetItemCount, S32, (),,