Переглянути джерело

Add getScriptPath console function to GUIAsset
Shifted tracking of importing asset status to an enum for more robust handling
Added logic to properly init freshly created shapeConstructors with the newly imported shapeAsset
Fixed handling of assets that have been marked to be skipped, but needed to fill in the parent's dependencies(UseForDependencies enum value)
Cleaned up redundant recursive logic for importing assets
Disable Create Game Objects button in inspector
Fixed material assignment for convex proxies
Updated asset icons for AB with WIP images to be more clear
Fixed issue where type-generic icons in the creator items in the AB weren't showing correctly.
Force AB to show creator entries in list mode for efficiency and avoid icon scaling issues
Moved creator functions for AB to separate file for convenience
Filled out GUIControls in the AB's creator mode, and context world editor and GUI creator entries based on active editor
Added drag-n-drop handling for guiControls via AB creator in guiEditor mode
Added more types' profiles in the AB gui profiles to give more unique border colors for better visual clarity of asset type
Added editor setting to indicate if the editor should load into the last edited level, or the editor default scene
Fixed setting of highlight material overlay in shapeEditor
Added global keybind for GUIEditor so space also toggles assetbrowser
Fixed up binding/finding of shapeConstructor by assetId, which also fixed displaying of shape's material listing

Areloch 4 роки тому
батько
коміт
8781f2ab55
44 змінених файлів з 680 додано та 733 видалено
  1. 7 0
      Engine/source/T3D/assets/GUIAsset.cpp
  2. 181 347
      Engine/source/T3D/assets/assetImporter.cpp
  3. 15 6
      Engine/source/T3D/assets/assetImporter.h
  4. 32 36
      Engine/source/T3D/tsStatic.cpp
  5. 8 9
      Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp
  6. 3 2
      Engine/source/scene/sceneObject.cpp
  7. 18 0
      Engine/source/ts/tsShapeConstruct.cpp
  8. 2 0
      Engine/source/ts/tsShapeConstruct.h
  9. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/animationIcon.png
  10. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/clientScriptIcon.png
  11. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/cppIcon.png
  12. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/datablockIcon.png
  13. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/folderIcon.png
  14. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/guiIcon.png
  15. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/levelIcon.png
  16. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/materialIcon.png
  17. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/postEffectIcon.png
  18. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/prefabIcon.png
  19. 8 0
      Templates/BaseGame/game/tools/assetBrowser/art/prefabIcon_image.asset.taml
  20. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/scriptIcon.png
  21. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/serverScriptIcon.png
  22. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/soundIcon.png
  23. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/stateMachineIcon.png
  24. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/terrainIcon.png
  25. 8 0
      Templates/BaseGame/game/tools/assetBrowser/art/terrainIcon_image.asset.taml
  26. BIN
      Templates/BaseGame/game/tools/assetBrowser/art/terrainMaterialIcon.png
  27. 4 0
      Templates/BaseGame/game/tools/assetBrowser/main.tscript
  28. 24 175
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript
  29. 0 142
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.tscript
  30. 13 0
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cpp.tscript
  31. 15 0
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/creatorObj.tscript
  32. 12 2
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript
  33. 1 1
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/prefab.tscript
  34. 16 0
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/script.tscript
  35. 6 5
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript
  36. 1 1
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrain.tscript
  37. 194 0
      Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript
  38. 63 0
      Templates/BaseGame/game/tools/assetBrowser/scripts/profiles.tscript
  39. 5 0
      Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript
  40. 0 0
      Templates/BaseGame/game/tools/gui/images/tab_border.png
  41. 1 1
      Templates/BaseGame/game/tools/gui/images/tab_border_image.asset.taml
  42. 12 3
      Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.tscript
  43. 28 0
      Templates/BaseGame/game/tools/main.tscript
  44. 3 3
      Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript

+ 7 - 0
Engine/source/T3D/assets/GUIAsset.cpp

@@ -221,6 +221,13 @@ DefineEngineStaticMethod(GUIAsset, getAssetIdByGUIName, const char*, (const char
 {
    return GUIAsset::getAssetIdByGUIName(StringTable->insert(guiName));
 }
+
+DefineEngineMethod(GUIAsset, getScriptPath, const char*, (), ,
+   "Gets the script file path associated to this asset.\n"
+   "@return The full script file path.")
+{
+   return object->getScriptPath();
+}
 #endif
 
 //-----------------------------------------------------------------------------

+ 181 - 347
Engine/source/T3D/assets/assetImporter.cpp

@@ -420,8 +420,7 @@ IMPLEMENT_CONOBJECT(AssetImportObject);
 
 AssetImportObject::AssetImportObject() :
    dirty(false),
-   skip(false),
-   processed(false),
+   importStatus(AssetImportObject::NotProcessed),
    generatedAsset(false),
    parentAssetItem(nullptr),
    tamlFilePath(""),
@@ -463,8 +462,6 @@ void AssetImportObject::initPersistFields()
    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("skip", TypeBool, Offset(skip, AssetImportObject), "Is this asset item marked to be skipped. If it is, it's usually due to being marked as deleted");
-   addField("processed", TypeBool, Offset(processed, AssetImportObject), "Has the asset item been processed");
    addField("generatedAsset", TypeBool, Offset(generatedAsset, AssetImportObject), "Is this specific asset item generated as part of the import process of another item");
 
    addField("tamlFilePath", TypeRealString, Offset(tamlFilePath, AssetImportObject), "What is the ultimate asset taml file path for this import item");
@@ -622,8 +619,7 @@ AssetImportObject* AssetImporter::addImportingAsset(String assetType, Torque::Pa
    assetImportObj->statusInfo = "";
 
    assetImportObj->dirty = false;
-   assetImportObj->skip = false;
-   assetImportObj->processed = false;
+   assetImportObj->importStatus = AssetImportObject::NotProcessed;
    assetImportObj->generatedAsset = false;
 
    if (parentItem != nullptr)
@@ -656,7 +652,7 @@ AssetImportObject* AssetImporter::addImportingAsset(String assetType, Torque::Pa
 
 void AssetImporter::deleteImportingAsset(AssetImportObject* assetItem)
 {
-   assetItem->skip = true;
+   assetItem->importStatus = AssetImportObject::Skipped;
 
    //log it
    dSprintf(importLogBuffer, sizeof(importLogBuffer), "Deleting Importing Asset %s and all it's child items", assetItem->assetName.c_str());
@@ -665,36 +661,21 @@ void AssetImporter::deleteImportingAsset(AssetImportObject* assetItem)
 
 AssetImportObject* AssetImporter::findImportingAssetByName(String assetName, AssetImportObject* assetItem)
 {
-   if (assetItem == nullptr)
-   {
-      for (U32 i = 0; i < importingAssets.size(); i++)
-      {
-         if (importingAssets[i]->cleanAssetName == assetName)
-         {
-            return importingAssets[i];
-         }
+   Vector<AssetImportObject*> itemList = importingAssets;
+   if (assetItem != nullptr)
+      itemList = assetItem->childAssetItems;
 
-         //If it wasn't a match, try recusing on the children(if any)
-         AssetImportObject* retItem = findImportingAssetByName(assetName, importingAssets[i]);
-         if (retItem != nullptr)
-            return retItem;
-      }
-   }
-   else
+   for (U32 i = 0; i < itemList.size(); i++)
    {
-      //this is the child recursing section
-      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+      if (itemList[i]->cleanAssetName == assetName)
       {
-         if (assetItem->childAssetItems[i]->cleanAssetName == assetName)
-         {
-            return assetItem->childAssetItems[i];
-         }
-
-         //If it wasn't a match, try recusing on the children(if any)
-         AssetImportObject* retItem = findImportingAssetByName(assetName, assetItem->childAssetItems[i]);
-         if (retItem != nullptr)
-            return retItem;
+         return 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;
@@ -1385,105 +1366,53 @@ void AssetImportConfig::loadSISFile(Torque::Path filePath)
 
 void AssetImporter::processImportAssets(AssetImportObject* assetItem)
 {
-   if (assetItem == nullptr)
-   {
-      assetHeirarchyChanged = false;
+   Vector<AssetImportObject*> itemList = importingAssets;
+   if (assetItem != nullptr)
+      itemList = assetItem->childAssetItems;
 
-      for (U32 i = 0; i < importingAssets.size(); i++)
-      {
-         AssetImportObject* item = importingAssets[i];
-         if (item->skip)
-            continue;
+   assetHeirarchyChanged = false;
 
-         if (!item->processed)
-         {
-            //Sanitize before modifying our asset name(suffix additions, etc)
-            if (item->assetName != item->cleanAssetName)
-               item->assetName = item->cleanAssetName;
+   for (U32 i = 0; i < itemList.size(); i++)
+   {
+      AssetImportObject* item = itemList[i];
+      if (item->importStatus != AssetImportObject::NotProcessed)
+         continue;
 
-            //handle special pre-processing here for any types that need it
+      //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"))
-               SoundAsset::prepareAssetForImport(this, 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->processed = true;
-         }
+      //handle special pre-processing here for any types that need it
 
-         //try recusing on the children(if any)
-         processImportAssets(item);
+      //process the asset items
+      if (item->assetType == String("ImageAsset"))
+      {
+         processImageAsset(item);
       }
-   }
-   else
-   {
-      //this is the child recursing section
-      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+      else if (item->assetType == String("ShapeAsset"))
       {
-         AssetImportObject* childItem = assetItem->childAssetItems[i];
-
-         if (childItem->skip)
-            continue;
-
-         if (!childItem->processed)
-         {
-            //Sanitize before modifying our asset name(suffix additions, etc)
-            //if (childItem->assetName != childItem->cleanAssetName)
-            //   childItem->assetName = childItem->cleanAssetName;
-
-            //handle special pre-processing here for any types that need it
-
-            //process the asset items
-            if (childItem->assetType == String("ImageAsset"))
-            {
-               processImageAsset(childItem);
-            }
-            else if (childItem->assetType == String("ShapeAsset"))
-            {
-               processShapeAsset(childItem);
-            }
-            /*else if (item->assetType == String("SoundAsset"))
-               SoundAsset::prepareAssetForImport(this, item);*/
-            else if (childItem->assetType == String("MaterialAsset"))
-            {
-               processMaterialAsset(childItem);
-            }
-            /*else if (item->assetType == String("ShapeAnimationAsset"))
-               ShapeAnimationAsset::prepareAssetForImport(this, item);*/
-            else
-            {
-               String processCommand = "process";
-               processCommand += childItem->assetType;
-               if (isMethod(processCommand.c_str()))
-                  Con::executef(this, processCommand.c_str(), childItem);
-            }
+         processShapeAsset(item);
+      }
+      /*else if (item->assetType == String("SoundAsset"))
+         SoundAsset::prepareAssetForImport(this, item);*/
+      else if (item->assetType == String("MaterialAsset"))
+      {
+         processMaterialAsset(item);
+      }
+      /*else if (item->assetType == String("ShapeAnimationAsset"))
+         ShapeAnimationAsset::prepareAssetForImport(this, item);*/
+      else
+      {
+         String processCommand = "process";
+         processCommand += item->assetType;
+         if(isMethod(processCommand.c_str()))
+            Con::executef(this, processCommand.c_str(), item);
+      }
 
-            childItem->processed = true;
-         }
+      item->importStatus == AssetImportObject::Processed;
 
-         //try recusing on the children(if any)
-         processImportAssets(childItem);
-      }
+      //try recusing on the children(if any)
+      processImportAssets(item);
    }
 
    //If our hierarchy changed, it's because we did so during processing
@@ -1606,7 +1535,7 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem)
       assetItem->cleanAssetName = assetItem->assetName;
    }
 
-   assetItem->processed = true;
+   assetItem->importStatus = AssetImportObject::Processed;
 }
 
 void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
@@ -1629,7 +1558,7 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
          String ignoredName = StringUnit::getUnit(activeImportConfig->IgnoreMaterials, i, ",;\t");
          if (FindMatch::isMatch(ignoredName.c_str(), assetName, false))
          {
-            assetItem->skip = true;
+            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);
@@ -1645,9 +1574,9 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
       //check to see if the definition for this already exists
       StringTableEntry existingMatAsset = MaterialAsset::getAssetIdByMaterialName(StringTable->insert(assetName));
 
-      if (existingMatAsset != StringTable->EmptyString())
+      if (existingMatAsset != StringTable->EmptyString() && existingMatAsset != StringTable->insert("Core_Rendering:NoMaterial"))
       {
-         assetItem->skip = true;
+         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;
@@ -1696,7 +1625,7 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
          {
             AssetImportObject* childAssetItem = assetItem->childAssetItems[i];
 
-            if (childAssetItem->skip || childAssetItem->assetType != String("ImageAsset"))
+            if (childAssetItem->importStatus == AssetImportObject::Skipped || childAssetItem->assetType != String("ImageAsset"))
                continue;
 
             for (S32 t = 0; t < ImageAsset::ImageTypeCount; t++)
@@ -1848,7 +1777,7 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
       }
    }
    
-   assetItem->processed = true;
+   assetItem->importStatus = AssetImportObject::Processed;
 }
 
 void AssetImporter::processShapeAsset(AssetImportObject* assetItem)
@@ -1944,7 +1873,7 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem)
    cachedConfig->CopyTo(activeImportConfig);
    cachedConfig->deleteObject();
 
-   assetItem->processed = true;
+   assetItem->importStatus = AssetImportObject::Processed;
 }
 
 void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 materialItemId)
@@ -2131,7 +2060,7 @@ void AssetImporter::processSoundAsset(AssetImportObject* assetItem)
       }
    }
 
-   assetItem->processed = true;
+   assetItem->importStatus = AssetImportObject::Processed;
 }
 //
 // Validation
@@ -2154,7 +2083,7 @@ bool AssetImporter::validateAssets()
 
 void AssetImporter::validateAsset(AssetImportObject* assetItem)
 {
-   if (assetItem->skip)
+   if (assetItem->importStatus == AssetImportObject::Skipped || assetItem->importStatus == AssetImportObject::NotProcessed)
       return;
 
    bool hasCollision = checkAssetForCollision(assetItem);
@@ -2234,36 +2163,21 @@ void AssetImporter::validateAsset(AssetImportObject* assetItem)
 
 void AssetImporter::resetAssetValidationStatus(AssetImportObject* assetItem)
 {
-   if (assetItem == nullptr)
-   {
-      for (U32 i = 0; i < importingAssets.size(); i++)
-      {
-         if (importingAssets[i]->skip)
-            continue;
-
-         importingAssets[i]->status = "";
-         importingAssets[i]->statusType = "";
-         importingAssets[i]->statusInfo = "";
+   Vector<AssetImportObject*> itemList = importingAssets;
+   if (assetItem != nullptr)
+      itemList = assetItem->childAssetItems;
 
-         //If it wasn't a match, try recusing on the children(if any)
-         resetAssetValidationStatus(importingAssets[i]);
-      }
-   }
-   else
+   for (U32 i = 0; i < itemList.size(); i++)
    {
-      //this is the child recursing section
-      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
-      {
-         if (assetItem->childAssetItems[i]->skip)
-            continue;
+      if (itemList[i]->importStatus == AssetImportObject::Skipped)
+         continue;
 
-         assetItem->childAssetItems[i]->status = "";
-         assetItem->childAssetItems[i]->statusType = "";
-         assetItem->childAssetItems[i]->statusInfo = "";
+      itemList[i]->status = "";
+      itemList[i]->statusType = "";
+      itemList[i]->statusInfo = "";
 
-         //If it wasn't a match, try recusing on the children(if any)
-         resetAssetValidationStatus(assetItem->childAssetItems[i]);
-      }
+      //If it wasn't a match, try recusing on the children(if any)
+      resetAssetValidationStatus(itemList[i]);
    }
 }
 
@@ -2271,68 +2185,37 @@ bool AssetImporter::checkAssetForCollision(AssetImportObject* assetItemToCheck,
 {
    bool results = false;
 
-   if (assetItem == nullptr)
-   {
-      for (U32 i = 0; i < importingAssets.size(); i++)
-      {
-         AssetImportObject* importingAsset = importingAssets[i];
-
-         if (importingAsset->skip)
-            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;
-         }
+   Vector<AssetImportObject*> itemList = importingAssets;
+   if (assetItem != nullptr)
+      itemList = assetItem->childAssetItems;
 
-         //If it wasn't a match, try recusing on the children(if any)
-         results = checkAssetForCollision(assetItemToCheck, importingAsset);
-         if (results)
-            return results;
-      }
-   }
-   else
+   for (U32 i = 0; i < itemList.size(); i++)
    {
-      //this is the child recursing section
-      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
-      {
-         AssetImportObject* childAsset = assetItem->childAssetItems[i];
+      AssetImportObject* importingAsset = itemList[i];
 
-         if (childAsset->skip)
-            continue;
+      if (importingAsset->importStatus == AssetImportObject::Skipped)
+         continue;
 
-         if ((assetItemToCheck->assetName.compare(childAsset->assetName) == 0) && (assetItemToCheck->getId() != childAsset->getId()))
-         {
-            //we do have a collision, note the collsion and bail out
-            assetItemToCheck->status = "Warning";
-            assetItemToCheck->statusType = "DuplicateImportAsset";
-            assetItemToCheck->statusInfo = "Duplicate asset names found with importing assets!\nAsset \"" + assetItem->assetName + "\" of the type \"" + assetItem->assetType + "\" and \"" +
-               assetItemToCheck->assetName + "\" of the type \"" + assetItemToCheck->assetType + "\" have matching names.\nPlease rename one of them.";
+      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(),
-               childAsset->assetName.c_str(), childAsset->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, childAsset);
-         if (results)
-            return results;
+         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;
@@ -2348,7 +2231,16 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem)
       if (activeImportConfig->DuplicateAutoResolution == String("AutoPrune"))
       {
          //delete the item
-         deleteImportingAsset(assetItem);
+         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());
@@ -2537,161 +2429,102 @@ void AssetImporter::importAssets(AssetImportObject* assetItem)
       return;
    }
 
-   if (assetItem == nullptr)
+   Vector<AssetImportObject*> itemList = importingAssets;
+   if (assetItem != nullptr)
+      itemList = assetItem->childAssetItems;
+
+   for (U32 i = 0; i < itemList.size(); i++)
    {
-      for (U32 i = 0; i < importingAssets.size(); i++)
+      AssetImportObject* item = itemList[i];
+      if (!item->canImport())
+         continue;
+
+      Torque::Path assetPath;
+      if (item->assetType == String("ImageAsset"))
       {
-         if (importingAssets[i]->skip)
-            continue;
+         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;
 
-         Torque::Path assetPath;
-         if (importingAssets[i]->assetType == String("ImageAsset"))
-         {
-            assetPath = importImageAsset(importingAssets[i]);
-         }
-         else if (importingAssets[i]->assetType == String("ShapeAsset"))
-         {
-            assetPath = importShapeAsset(importingAssets[i]);
-         }
-         else if (importingAssets[i]->assetType == String("SoundAsset"))
+         String processCommand = "import";
+         processCommand += item->assetType;
+         if (isMethod(processCommand.c_str()))
          {
-            assetPath = importSoundAsset(importingAssets[i]);
-         }
-         else if (importingAssets[i]->assetType == String("MaterialAsset"))
-         {
-            assetPath = importMaterialAsset(importingAssets[i]);
-         }
-         else
-         {
-            finalImportedAssetPath = String::EmptyString;
-
-            String processCommand = "import";
-            processCommand += importingAssets[i]->assetType;
-            if (isMethod(processCommand.c_str()))
-            {
-               Con::executef(this, processCommand.c_str(), importingAssets[i]);
+            Con::executef(this, processCommand.c_str(), item);
 
-               assetPath = finalImportedAssetPath;
-            }
+            assetPath = finalImportedAssetPath;
          }
-         /*else if (importingAssets[i]->assetType == String("ShapeAnimationAsset"))
-            assetPath = ShapeAnimationAsset::importAsset(importingAssets[i]);*/
+      }
+      /*else if (importingAssets[i]->assetType == String("ShapeAnimationAsset"))
+         assetPath = ShapeAnimationAsset::importAsset(importingAssets[i]);*/
 
-         if (assetPath.isEmpty() && importingAssets[i]->assetType != String("MaterialAsset"))
-         {
-            dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Import attempt of %s failed, so skipping asset.", importingAssets[i]->assetName.c_str());
-            activityLog.push_back(importLogBuffer);
+      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
+         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)
          {
-            //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());
+            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);
-               }
+            if (!registerSuccess)
+            {
+               dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to successfully register new asset at path %s to moduleId %s", assetPath.getFullPath().c_str(), targetModuleId.c_str());
+               activityLog.push_back(importLogBuffer);
             }
             else
             {
-               String assetId = importingAssets[i]->moduleName + ":" + importingAssets[i]->assetName;
-               bool refreshSuccess = AssetDatabase.refreshAsset(assetId.c_str());
-
-               if (!refreshSuccess)
+               //Any special-case post-reg stuff here
+               if (item->assetType == String("ShapeAsset"))
                {
-                  dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to refresh reimporting asset %s.", importingAssets[i]->assetName.c_str());
-                  activityLog.push_back(importLogBuffer);
-               }
-            }
-         }
+                  String assetIdStr = item->moduleName + ":" + item->assetName;
+                  StringTableEntry assetId = StringTable->insert(assetIdStr.c_str());
 
-         //recurse if needed
-         importAssets(importingAssets[i]);
-      }
-   }
-   else
-   {
-      //this is the child recursing section
-      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
-      {
-         AssetImportObject* childItem = assetItem->childAssetItems[i];
-
-         if (childItem->skip)
-            continue;
-
-         Torque::Path assetPath;
-         if (childItem->assetType == String("ImageAsset"))
-         {
-            assetPath = importImageAsset(childItem);
-         }
-         else if (childItem->assetType == String("ShapeAsset"))
-         {
-            assetPath = importShapeAsset(childItem);
-         }
-         else if (childItem->assetType == String("SoundAsset"))
-         {
-            assetPath = importSoundAsset(childItem);
-         }
-         else if (childItem->assetType == String("MaterialAsset"))
-         {
-            assetPath = importMaterialAsset(childItem);
-         }
-         /*else if (childItem->assetType == String("ShapeAnimationAsset"))
-            assetPath = ShapeAnimationAsset::importAsset(childItem);*/
-         else
-         {
-            finalImportedAssetPath = String::EmptyString;
+                  //forcefully update it's shape constructor
+                  TSShapeConstructor* tss = TSShapeConstructor::findShapeConstructorByAssetId(assetId);
 
-            String processCommand = "import";
-            processCommand += childItem->assetType;
-            if (isMethod(processCommand.c_str()))
-            {
-               ConsoleValueRef importReturnVal = Con::executef(this, processCommand.c_str(), childItem);
-               assetPath = Torque::Path(importReturnVal.getStringValue());
+                  if(tss)
+                     tss->setShapeAssetId(assetId);
+               }
             }
          }
-
-         if (assetPath.isEmpty() && childItem->assetType != String("MaterialAsset"))
-         {
-            dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Import attempt of %s failed, so skipping asset.", childItem->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());
+            String assetId = item->moduleName + ":" + item->assetName;
+            bool refreshSuccess = AssetDatabase.refreshAsset(assetId.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
+            if (!refreshSuccess)
             {
-               String assetId = childItem->moduleName + ":" + childItem->assetName;
-               bool refreshSuccess = AssetDatabase.refreshAsset(assetId.c_str());
-
-               if (!refreshSuccess)
-               {
-                  dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to refresh reimporting asset %s.", childItem->assetName.c_str());
-                  activityLog.push_back(importLogBuffer);
-               }
+               dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to refresh reimporting asset %s.", item->assetName.c_str());
+               activityLog.push_back(importLogBuffer);
             }
          }
-
-         //recurse if needed
-         importAssets(childItem);
       }
+
+      //Mark us as successfully imported
+      item->importStatus = AssetImportObject::Imported;
+
+      //recurse if needed
+      importAssets(item);
    }
 }
 
@@ -2796,7 +2629,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
    {
       AssetImportObject* childItem = assetItem->childAssetItems[i];
 
-      if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
+      if ((!childItem->canImport() && childItem->importStatus != AssetImportObject::UseForDependencies) || childItem->assetType.compare("ImageAsset") != 0)
          continue;
 
       char dependencyFieldName[64];
@@ -2833,7 +2666,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
       {
          AssetImportObject* childItem = assetItem->childAssetItems[i];
 
-         if (childItem->skip || childItem->assetType.compare("ImageAsset") != 0)
+         if (childItem->canImport() || childItem->assetType.compare("ImageAsset") != 0)
             continue;
 
          if (childItem->imageSuffixType.compare("ORMConfig") == 0)
@@ -2890,7 +2723,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
             {
                AssetImportObject* childItem = assetItem->childAssetItems[i];
 
-               if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
+               if (childItem->canImport() || childItem->assetType.compare("ImageAsset") != 0)
                   continue;
 
                String path = childItem->filePath.getFullFileName();
@@ -2967,7 +2800,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
       {
          AssetImportObject* childItem = assetItem->childAssetItems[i];
 
-         if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
+         if ((!childItem->canImport() && childItem->importStatus != AssetImportObject::UseForDependencies) || childItem->assetType.compare("ImageAsset") != 0)
             continue;
 
          String mapFieldName = "";
@@ -3090,7 +2923,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
    {
       AssetImportObject* childItem = assetItem->childAssetItems[i];
 
-      if (childItem->skip || !childItem->processed)
+      if (!childItem->canImport() && childItem->importStatus != AssetImportObject::UseForDependencies)
          continue;
 
       if (childItem->assetType.compare("MaterialAsset") == 0)
@@ -3195,7 +3028,8 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
       TSShapeConstructor* constructor = TSShapeConstructor::findShapeConstructorByFilename(Torque::Path(qualifiedToFile).getFullPath());
       if (constructor == nullptr)
       {
-         constructor = new TSShapeConstructor(StringTable->insert(qualifiedToFile));
+         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(" ", "_");

+ 15 - 6
Engine/source/T3D/assets/assetImporter.h

@@ -492,15 +492,20 @@ public:
    /// </summary>
    bool dirty;
 
-   /// <summary>
-   /// Is this asset item marked to be skipped. If it is, it's usually due to being marked as deleted
-   /// </summary>
-   bool skip;
+   enum
+   {
+      NotProcessed=0,
+      Processed,
+      Skipped,
+      UseForDependencies,
+      Error,
+      Imported
+   };
 
    /// <summary>
-   /// Has the asset item been processed
+   /// Is this asset item marked to be skipped. If it is, it's usually due to being marked as deleted
    /// </summary>
-   bool processed;
+   U32 importStatus;
 
    /// <summary>
    /// Is this specific asset item generated as part of the import process of another item
@@ -564,6 +569,10 @@ public:
    {
       return o.getId() == this->getId();
    }
+
+   bool canImport() {
+      return (importStatus == AssetImportObject::Processed);
+   }
 };
 
 /// <summary>

+ 32 - 36
Engine/source/T3D/tsStatic.cpp

@@ -1015,7 +1015,7 @@ U32 TSStatic::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
          con->packNetStringHandleU(stream, matNameStr);
       }
 
-      mChangingMaterials.clear();
+      //mChangingMaterials.clear();
    }
 
    return retMask;
@@ -1670,53 +1670,49 @@ void TSStatic::onInspect(GuiInspector* inspector)
       {
          StringTableEntry materialname = StringTable->insert(mShapeAsset->getShape()->materialList->getMaterialName(i).c_str());
 
-         //Iterate through our assetList to find the compliant entry in our matList
-         for (U32 m = 0; m < mShapeAsset->getMaterialCount(); m++)
+         AssetPtr<MaterialAsset> matAsset;
+         if(MaterialAsset::getAssetByMaterialName(materialname, &matAsset) == MaterialAsset::Ok)
          {
-            AssetPtr<MaterialAsset> matAsset = mShapeAsset->getMaterialAsset(m);
-
-            if (matAsset->getMaterialDefinitionName() == materialname)
-            {
-               dSprintf(matFieldName, 128, "MaterialSlot%d", i);
+            dSprintf(matFieldName, 128, "MaterialSlot%d", i);
 
-               //addComponentField(matFieldName, "A material used in the shape file", "Material", matAsset->getAssetId(), "");
-               //Con::executef(this, "onConstructComponentField", mTargetComponent, field->mFieldName);
-               Con::printf("Added material field for MaterialSlot %d", i);
+            //addComponentField(matFieldName, "A material used in the shape file", "Material", matAsset->getAssetId(), "");
+            //Con::executef(this, "onConstructComponentField", mTargetComponent, field->mFieldName);
+            Con::printf("Added material field for MaterialSlot %d", i);
 
-               GuiInspectorField* fieldGui = materialGroup->constructField(TypeMaterialAssetPtr);
-               fieldGui->init(inspector, materialGroup);
+            GuiInspectorField* fieldGui = materialGroup->constructField(TypeMaterialAssetPtr);
+            fieldGui->init(inspector, materialGroup);
 
-               fieldGui->setSpecialEditField(true);
-               fieldGui->setTargetObject(this);
+            fieldGui->setSpecialEditField(true);
+            fieldGui->setTargetObject(this);
 
-               StringTableEntry fldnm = StringTable->insert(matFieldName);
+            StringTableEntry fldnm = StringTable->insert(matFieldName);
 
-               fieldGui->setSpecialEditVariableName(fldnm);
+            fieldGui->setSpecialEditVariableName(fldnm);
 
-               fieldGui->setInspectorField(NULL, fldnm);
-               fieldGui->setDocs("");
+            fieldGui->setInspectorField(NULL, fldnm);
+            fieldGui->setDocs("");
 
-               if (fieldGui->registerObject())
-               {
-                  fieldGui->setValue(materialname);
+            if (fieldGui->registerObject())
+            {
+               StringTableEntry fieldValue = matAsset->getAssetId();
 
-                  stack->addObject(fieldGui);
-               }
-               else
+               //Check if we'd already actually changed it, and display the modified value
+               for (U32 c = 0; c < mChangingMaterials.size(); c++)
                {
-                  SAFE_DELETE(fieldGui);
+                  if (mChangingMaterials[c].slot == i)
+                  {
+                     fieldValue = StringTable->insert(mChangingMaterials[i].assetId.c_str());
+                     break;
+                  }
                }
 
-               /*if (materialGroup->isMethod("onConstructField"))
-               {
-                  //ensure our stack variable is bound if we need it
-                  //Con::evaluatef("%d.stack = %d;", materialGroup->getId(), materialGroup->at(0)->getId());
-
-                  Con::executef(materialGroup, "onConstructField", matFieldName,
-                     matFieldName, "material", matFieldName,
-                     materialname, "", "", this);
-               }*/
-               break;
+               fieldGui->setValue(fieldValue);
+
+               stack->addObject(fieldGui);
+            }
+            else
+            {
+               SAFE_DELETE(fieldGui);
             }
          }
       }

+ 8 - 9
Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp

@@ -236,7 +236,7 @@ void GuiConvexEditorCtrl::setVisible( bool val )
                bool isPortal = (scene->at(c)->getClassName() == StringTable->insert("Portal"));
                bool isOccluder = (scene->at(c)->getClassName() == StringTable->insert("OcclusionVolume"));
 
-               if (isZone || isPortal || isOccluder)
+               if (isTrigger || isZone || isPortal || isOccluder)
                {
                   SceneObject* sceneObj = static_cast<SceneObject*>(scene->at(c));
                   if (!sceneObj)
@@ -247,15 +247,18 @@ void GuiConvexEditorCtrl::setVisible( bool val )
 
                   ConvexShape* proxyShape = createConvexShapeFrom(sceneObj);
 
+                  if (proxyShape == NULL)
+                     continue;
+
                   //Set the texture to a representatory one so we know what's what
                   if (isTrigger)
-                     proxyShape->mMaterialName = "ToolsModule:TriggerProxyMaterial";
+                     proxyShape->_setMaterial(StringTable->insert("ToolsModule:TriggerProxyMaterial"));
                   else if (isPortal)
-                     proxyShape->mMaterialName = "ToolsModule:PortalProxyMaterial";
+                     proxyShape->_setMaterial(StringTable->insert("ToolsModule:PortalProxyMaterial"));
                   else if (isZone)
-                     proxyShape->mMaterialName = "ToolsModule:ZoneProxyMaterial";
+                     proxyShape->_setMaterial(StringTable->insert("ToolsModule:ZoneProxyMaterial"));
                   else if (isOccluder)
-                     proxyShape->mMaterialName = "ToolsModule:OccluderProxyMaterial";
+                     proxyShape->_setMaterial(StringTable->insert("ToolsModule:OccluderProxyMaterial"));
 
                   proxyShape->_updateMaterial();
 
@@ -707,8 +710,6 @@ void GuiConvexEditorCtrl::on3DMouseDragged(const Gui3DMouseEvent & event)
 
                float zRot = mRadToDeg(newSufRot.z - curSufRot.z);
 
-               float curZRot = mConvexSEL->mSurfaceUVs[mFaceSEL].zRot;
-
                mConvexSEL->mSurfaceUVs[mFaceSEL].zRot += zRot;
             }
 
@@ -2005,8 +2006,6 @@ void GuiConvexEditorCtrl::setSelectedFaceMaterial(const char* materialName)
    //run through and find out if there are any other faces still using the old mat texture
    if (oldmatID != 0)
    {
-      S32 curMatCount = mConvexSEL->mSurfaceTextures.size();
-
       bool used = false;
       for (U32 i = 0; i < mConvexSEL->mSurfaceUVs.size(); i++)
       {

+ 3 - 2
Engine/source/scene/sceneObject.cpp

@@ -631,12 +631,13 @@ void SceneObject::setHidden( bool hidden )
 
 void SceneObject::initPersistFields()
 {
-   addGroup("GameObject");
+   //Disabled temporarily
+   /*addGroup("GameObject");
    addField("GameObject", TypeGameObjectAssetPtr, Offset(mGameObjectAsset, SceneObject), "The asset Id used for the game object this entity is based on.");
 
    addField("dirtyGameObject", TypeBool, Offset(mDirtyGameObject, SceneObject), "If this entity is a GameObject, it flags if this instance delinates from the template.",
       AbstractClassRep::FieldFlags::FIELD_HideInInspectors);
-   endGroup("GameObject");
+   endGroup("GameObject");*/
 
    addGroup( "Transform" );
 

+ 18 - 0
Engine/source/ts/tsShapeConstruct.cpp

@@ -556,6 +556,24 @@ void TSShapeConstructor::_onUnload()
    mShape = NULL;
 }
 
+//-----------------------------------------------------------------------------
+void TSShapeConstructor::setShapeAssetId(StringTableEntry assetId)
+{
+   mShapeAssetId = assetId;
+   mShapeAsset = mShapeAssetId;
+   if (mShapeAsset.notNull())
+   {
+      Resource<TSShape> shape = mShapeAsset->getShapeResource();
+
+      if (shape)
+         _onLoad(shape);
+   }
+
+   if (mShape && mShape->needsReinit())
+   {
+      mShape->init();
+   }
+}
 //-----------------------------------------------------------------------------
 // Storage
 

+ 2 - 0
Engine/source/ts/tsShapeConstruct.h

@@ -222,6 +222,8 @@ public:
 
    void notifyShapeChanged();
 
+   void setShapeAssetId(StringTableEntry assetId);
+
    /// @name Shape paths for MeshFit
    ///@{
    static const String& getCapsuleShapePath() { return smCapsuleShapePath; }

BIN
Templates/BaseGame/game/tools/assetBrowser/art/animationIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/clientScriptIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/cppIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/datablockIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/folderIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/guiIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/levelIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/materialIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/postEffectIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/prefabIcon.png


+ 8 - 0
Templates/BaseGame/game/tools/assetBrowser/art/prefabIcon_image.asset.taml

@@ -0,0 +1,8 @@
+<ImageAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="prefabIcon_image"
+    imageFile="@assetFile=prefabIcon.png"
+    UseMips="true"
+    isHDRImage="false"
+    imageType="Albedo" />

BIN
Templates/BaseGame/game/tools/assetBrowser/art/scriptIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/serverScriptIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/soundIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/stateMachineIcon.png


BIN
Templates/BaseGame/game/tools/assetBrowser/art/terrainIcon.png


+ 8 - 0
Templates/BaseGame/game/tools/assetBrowser/art/terrainIcon_image.asset.taml

@@ -0,0 +1,8 @@
+<ImageAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="terrainMaterialIcon_image"
+    imageFile="@assetFile=terrainMaterialIcon.png"
+    UseMips="true"
+    isHDRImage="false"
+    imageType="Albedo" />

BIN
Templates/BaseGame/game/tools/assetBrowser/art/terrainMaterialIcon.png


+ 4 - 0
Templates/BaseGame/game/tools/assetBrowser/main.tscript

@@ -84,6 +84,7 @@ function initializeAssetBrowser()
    exec("./scripts/directoryHandling." @ $TorqueScriptFileExtension);
    exec("./scripts/selectPath." @ $TorqueScriptFileExtension);
    exec("./scripts/looseFileAudit." @ $TorqueScriptFileExtension);
+   exec("./scripts/creator." @ $TorqueScriptFileExtension);
    
    //Processing for the different asset types
    exec("./scripts/assetTypes/component." @ $TorqueScriptFileExtension); 
@@ -152,6 +153,9 @@ function initializeAssetBrowser()
    ImportAssetWindow.importingFilesArray = new ArrayObject();
       
    ImportAssetWindow.importer = new AssetImporter();
+   
+   if(!isObject(AssetBrowserCreatorGroupsList))
+      new ArrayObject(AssetBrowserCreatorGroupsList);
       
    AssetBrowser.buildPopupMenus();
    

+ 24 - 175
Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript

@@ -512,7 +512,7 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName )
       AssetBrowser-->previewSlider.setValue(1);
    }
    
-   if(%previewScaleSize == 0)
+   if(%previewScaleSize == 0 || startsWith(AssetBrowser.dirHandler.currentAddress, "Creator"))
    {
       %previewButton.iconLocation = "Left";
       %previewButton.textLocation = "Right";
@@ -830,137 +830,6 @@ function AssetBrowser::setTagActive(%this, %tag)
    %this.rebuildAssetArray();
 }
 
-function AssetBrowser::loadCreatorClasses(%this)
-{
-   // Just so we can recall this method for testing changes
-   // without restarting.
-   if ( isObject( %this.creatorClassArray ) )
-      %this.creatorClassArray.delete();
-      
-   %this.creatorClassArray = new ArrayObject();
-   %this.creatorClassArray.caseSensitive = true; 
-   //%this.setListView( true );
-   
-   %this.beginCreatorGroup( "Environment" );
-   
-      // Removed Prefab as there doesn't really seem to be a point in creating a blank one
-      //%this.addCreatorClass( "Prefab",              "Prefab" );
-      %this.addCreatorClass( "SkyBox",              "Sky Box" );
-      %this.addCreatorClass( "CloudLayer",          "Cloud Layer" );
-      %this.addCreatorClass( "BasicClouds",         "Basic Clouds" );
-      %this.addCreatorClass( "ScatterSky",          "Scatter Sky" );
-      %this.addCreatorClass( "Sun",                 "Basic Sun" );
-      %this.addCreatorClass( "Lightning" );
-      %this.addCreatorClass( "WaterBlock",          "Water Block" );
-      %this.addCreatorClass( "SFXEmitter",          "Sound Emitter" );
-      %this.addCreatorClass( "Precipitation" );
-      %this.addCreatorClass( "ParticleEmitterNode", "Particle Emitter" );
-      
-      // Legacy features. Users should use Ground Cover and the Forest Editor.   
-      //%this.addCreatorClass( "fxShapeReplicator",   "Shape Replicator" );
-      //%this.addCreatorClass( "fxFoliageReplicator", "Foliage Replicator" );
-      
-      %this.addCreatorClass( "PointLight",          "Point Light" );
-      %this.addCreatorClass( "SpotLight",           "Spot Light" );
-      %this.addCreatorClass( "GroundCover",         "Ground Cover" );
-      %this.addCreatorClass( "TerrainBlock",        "Terrain Block" );
-      %this.addCreatorClass( "GroundPlane",         "Ground Plane" );
-      %this.addCreatorClass( "WaterPlane",          "Water Plane" );
-      %this.addCreatorClass( "PxCloth",             "Cloth" );
-      %this.addCreatorClass( "ForestWindEmitter",   "Wind Emitter" );
-               
-      %this.addCreatorClass( "DustEmitter", "Dust Emitter" );
-      %this.addCreatorClass( "DustSimulation", "Dust Simulation" );
-      %this.addCreatorClass( "DustEffecter", "Dust Effecter" );
-      
-   %this.endCreatorGroup();
-
-   %this.beginCreatorGroup( "Level" );
-   
-      %this.addCreatorClass("MissionArea",  "Mission Area" );
-      %this.addCreatorClass("Path" );
-      %this.addCreatorClass("Marker",       "Path Node" );
-      %this.addCreatorClass("Trigger" );
-      %this.addCreatorClass("PhysicalZone", "Physical Zone" );
-      %this.addCreatorClass("Camera" );
-      %this.addCreatorClass( "LevelInfo",    "Level Info" );
-      %this.addCreatorClass( "TimeOfDay",    "Time of Day" );
-      %this.addCreatorClass( "Zone",         "Zone" );
-      %this.addCreatorClass( "Portal",       "Zone Portal" );
-      %this.addCreatorClass( "SpawnSphere",  "Player Spawn Sphere"/*, "PlayerDropPoint"*/ );
-      %this.addCreatorClass( "SpawnSphere",  "Observer Spawn Sphere"/*, "ObserverDropPoint"*/ );
-      %this.addCreatorClass( "SFXSpace",      "Sound Space" );
-      %this.addCreatorClass( "OcclusionVolume", "Occlusion Volume" );
-      
-   %this.endCreatorGroup();
-   
-   %this.beginCreatorGroup( "System" );
-   
-      %this.addCreatorClass( "SimGroup" );
-      %this.addCreatorClass( "AIPathGroup" );
-      
-   %this.endCreatorGroup();  
-
-   %this.beginCreatorGroup( "ExampleObjects" );
-   
-      %this.addCreatorClass( "RenderObjectExample" );
-      %this.addCreatorClass( "RenderMeshExample" );
-      %this.addCreatorClass( "RenderShapeExample" );
-      
-   %this.endCreatorGroup(); 
-   
-   %this.creatorClassArray.sortk();
-}
-
-function AssetBrowser::beginCreatorGroup(%this, %group)
-{
-   AssetBrowser-->filterTree.insertItem(AssetBrowser-->filterTree.creatorIdx, %group);
-   %this.currentCreatorGroup = %group;
-}
-
-function AssetBrowser::endCreatorGroup(%this, %group)
-{
-   %this.currentCreatorGroup = "";
-}
-
-function AssetBrowser::addCreatorClass(%this, %class, %name, %buildfunc)
-{
-   if( !isClass(%class) )
-      return;
-      
-   if ( %name $= "" )
-      %name = %class;
-      
-   if ( %this.currentCreatorGroup !$= "" && %group $= "" )
-      %group = %this.currentCreatorGroup;
-   
-   if ( %class $= "" || %group $= "" )
-   {
-      warn( "AssetBrowser::addCreatorClass, invalid parameters!" );
-      return;  
-   }
-   
-   if(%buildfunc $= "")
-   {
-      %method = "build" @ %buildfunc;
-      if( !ObjectBuilderGui.isMethod( %method ) )
-         %method = "build" @ %class;
-
-      if( !ObjectBuilderGui.isMethod( %method ) )
-         %cmd = "return new " @ %class @ "();";
-      else
-         %cmd = "ObjectBuilderGui." @ %method @ "();";
-
-      %buildfunc = "ObjectBuilderGui.newObjectCallback = \"AssetBrowser.onFinishCreateObject\"; EWCreatorWindow.createObject( \"" @ %cmd @ "\" );";
-   }
-
-   %args = new ScriptObject();
-   %args.val[0] = %class;
-   %args.val[1] = %name;
-   %args.val[2] = %buildfunc;
-   
-   %this.creatorClassArray.push_back( %group, %args );
-}
 //
 //needs to be deleted with the persistence manager and needs to be blanked out of the matmanager
 //also need to update instances... i guess which is the tricky part....
@@ -1474,47 +1343,6 @@ function AssetBrowser::doRebuildAssetArray(%this)
 			   %assetType = AssetDatabase.getAssetType(%assetId);
 			}
 			
-			/*%validType = false;
-         
-         if(AssetBrowser.assetTypeFilter $= "")
-         {
-            if(AssetTypeListPopup.isItemChecked(0))
-            {
-               %validType = true;
-            }
-            else
-            {
-               for(%f=1; %f < AssetFilterTypeList.Count(); %f++)
-               {
-                  %isChecked = AssetTypeListPopup.isItemChecked(%f+1);  
-                  
-                  if(%isChecked)
-                  {
-                     %filterTypeName = AssetFilterTypeList.getKey(%f);
-                     
-                     if(%activeTypeFilterList $= "")
-                        %activeTypeFilterList = %filterTypeName;
-                     else
-                        %activeTypeFilterList = %activeTypeFilterList @ ", " @ %filterTypeName;
-                        
-                     if(%filterTypeName @ "Asset" $= %assetType)
-                     {
-                        %validType = true;
-                        break;  
-                     }
-                  }
-               }
-            }
-            
-            if(!%validType)
-               continue;
-         }
-         else
-         {
-            if(%assetType !$= AssetBrowser.assetTypeFilter)
-               continue;  
-         }*/
-			
          //stop adding after previewsPerPage is hit
          %assetName = AssetDatabase.getAssetName(%assetId);
 
@@ -1589,7 +1417,7 @@ function AssetBrowser::doRebuildAssetArray(%this)
    }
 
    //Add Non-Asset Scripted Objects. Datablock, etc based
-   if(AssetBrowser.assetTypeFilter $= "" && %breadcrumbPath !$= "" && !startsWith(%breadcrumbPath, "Creator/"))
+   if(AssetBrowser.assetTypeFilter $= "" && %breadcrumbPath !$= "" && isDirectory(%breadcrumbPath))
    {
       %category = getWord( %breadcrumbPath, 1 );                  
       %dataGroup = "DataBlockGroup";
@@ -1779,11 +1607,28 @@ function AssetBrowser::doRebuildAssetArray(%this)
       //One of the creator folders was selected
       %creatorGroup = AssetBrowserFilterTree.getItemText(AssetBrowserFilterTree.getSelectedItem(0));
             
+      if(%creatorGroup $= "Creator")
+      {
+         //add folders for the groups
+         %placeholderVar = "";
+      }
+      else
+      {
       for ( %i = 0; %i < AssetBrowser.creatorClassArray.count(); %i++ )
       {
          %group = AssetBrowser.creatorClassArray.getKey( %i );
 
-         if ( %group $= %creatorGroup )
+            //Do some filter logic do skip out of groups if we're in the wrong editor mode for it
+            %creatorEditorFilter = "WorldEditor";
+            if(GuiEditorIsActive())
+            {
+               %creatorEditorFilter = "GuiEditor";
+            }
+            
+            %creatorGroupIndex = AssetBrowserCreatorGroupsList.getIndexFromValue(%group);
+            %creatorGroupKey = AssetBrowserCreatorGroupsList.getKey(%creatorGroupIndex);
+            
+            if ( %group $= %creatorGroup && %creatorGroupKey $= %creatorEditorFilter )
          {
             %creatorObj = AssetBrowser.creatorClassArray.getValue( %i );
             %class = %creatorObj.val[0];
@@ -1794,6 +1639,7 @@ function AssetBrowser::doRebuildAssetArray(%this)
          }               
       }   
 	}
+	}
 	
    for(%i=0; %i < $AssetBrowser::AssetArray.count(); %i++)
 		AssetBrowser.buildAssetPreview( $AssetBrowser::AssetArray.getValue(%i), $AssetBrowser::AssetArray.getKey(%i) );  
@@ -2519,6 +2365,9 @@ function AssetBrowserFilterTree::onDragDropped( %this )
 
 function AssetBrowser::hasLooseFilesInDir(%this)
 {
+   if(!isDirectory(%this.dirHandler.currentAddress))
+      return false;
+   
    //First, wipe out any files inside the folder first
    %file = findFirstFileMultiExpr( %this.dirHandler.currentAddress @ "/*.*", false);
    

+ 0 - 142
Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.tscript

@@ -410,63 +410,6 @@ function ImportAssetWindow::reloadImportOptionConfigs(%this)
    //ImportAssetConfigList.setSelected(%importConfigIdx);
 }
 
-//
-/*function importLooseFile(%filePath, %forceAutoImport)
-{
-   %assetType = getAssetTypeByFilename(%filePath);
-   
-   if(%forceAutoImport)
-   {
-      //If we're attempting to fast-track the import, check that that's even an option
-      if(ImportAssetWindow.importConfigsList.count() == 0 || 
-      EditorSettings.value("Assets/AssetImporDefaultConfig") $= "" || 
-      EditorSettings.value("Assets/AutoImport", false) == false)
-      {
-         toolsMessageBoxOK("Unable to AutoImport", "Attempted to import a loose file " @ %filePath @ " with AutoImport but was unable to either due to lacking a valid import config, or the editor settings are not set to auto import.");
-         return false;      
-      }
-      
-      if(%assetType $= "folder" || %assetType $= "zip")
-      {
-         toolsMessageBoxOK("Unable to AutoImport", "Unable to auto import folders or zips at this time");
-         return false; 
-      }
-      
-      if(%assetType $= "")
-      {
-         toolsMessageBoxOK("Unable to AutoImport", "Unable to auto import unknown file type for file " @ %filePath);
-         return false; 
-      }
-   }
-   
-   %assetItem = AssetBrowser.addImportingAsset(%assetType, %filePath, "", "");
-   ImportAssetItems.add(%assetItem);
-   
-   if(%forceAutoImport)
-   {
-      %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(filePath(%filePath)).ModuleId;
-      AssetImportTargetModule.text = %targetModule;
-      
-      %assetItem.moduleName = %targetModule;
-      
-      %assetName = %assetItem.assetName;
-      
-      AssetBrowser.dirHandler.currentAddress = filePath(%filePath);
-      
-      //skip the refresh delay, we'll force it here
-      ImportAssetWindow.doRefresh();
-      
-      ImportAssetItems.empty();
-      
-      if(ImportAssetWindow.hasImportIssues)
-         return false;
-   }
-   
-   $importedLooseFileAsset = %assetItem.moduleName @ ":" @ %assetItem.assetName;
-   
-   return true;
-}*/
-
 //
 function assetImportUpdatePath(%newPath)
 {
@@ -475,91 +418,6 @@ function assetImportUpdatePath(%newPath)
    AssetImportTargetModule.text = AssetBrowser.dirHandler.getModuleFromAddress(AssetBrowser.dirHandler.currentAddress).ModuleId;
 }
 
-//
-/*function ImportAssetWindow::processImportAssets(%this, %assetItem)
-{
-   if(!isObject(%assetItem))
-   {
-      //Zero this out
-      ImportAssetWindow.assetHeirarchyChanged = false;
-      
-      for(%i=0; %i < ImportAssetItems.count(); %i++)
-      {
-         %assetItem = ImportAssetItems.getKey(%i);
-         
-         if(!isObject(%assetItem) || %assetItem.skip )
-            return;
-            
-         if(%assetItem.processed == false)
-         {
-            //sanetize before modifying our asset name(suffix additions, etc)      
-            if(%assetItem.assetName !$= %assetItem.cleanAssetName)
-               %assetItem.assetName = %assetItem.cleanAssetName;
-            
-            if(%assetItem.assetType $= "AnimationAsset")
-            {
-               //if we don't have our own file, that means we're gunna be using our parent shape's file so reference that
-               if(!isFile(%assetItem.filePath))
-               {
-                  %assetItem.filePath = %assetItem.parentAssetItem.filePath;
-               }
-            }
-            
-            if(AssetBrowser.isMethod("prepareImport" @ %assetItem.assetType))
-            {
-               %command = AssetBrowser @ ".prepareImport" @ %assetItem.assetType @ "(" @ %assetItem @ ");";
-               eval(%command);
-            }
-            
-            %assetItem.processed = true;
-         }
-         
-         %this.processImportAssets(%assetItem);
-      }
-   }
-   else
-   {
-      for(%i=0; %i < %assetItem.childAssetItems.count(); %i++)
-      {
-         %childAssetItem = %assetItem.childAssetItems.getKey(%i);
-         
-         if(!isObject(%childAssetItem) || %childAssetItem.skip)
-            return;
-            
-         if(%childAssetItem.processed == false)
-         {
-            //sanetize before modifying our asset name(suffix additions, etc)      
-            if(%childAssetItem.assetName !$= %childAssetItem.cleanAssetName)
-               %childAssetItem.assetName = %childAssetItem.cleanAssetName;
-            
-            if(%childAssetItem.assetType $= "AnimationAsset")
-            {
-               //if we don't have our own file, that means we're gunna be using our parent shape's file so reference that
-               if(!isFile(%childAssetItem.filePath))
-               {
-                  %childAssetItem.filePath = %childAssetItem.parentAssetItem.filePath;
-               }
-            }
-            
-            if(AssetBrowser.isMethod("prepareImport" @ %childAssetItem.assetType))
-            {
-               %command = AssetBrowser @ ".prepareImport" @ %childAssetItem.assetType @ "(" @ %childAssetItem @ ");";
-               eval(%command);
-            }
-            
-            %childAssetItem.processed = true;
-         }
-         
-         %this.processImportAssets(%childAssetItem);
-      }
-   }
-   
-   //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(ImportAssetWindow.assetHeirarchyChanged)
-      %this.processImportAssets();
-}*/
-
 function ImportAssetWindow::findImportingAssetByName(%this, %assetName, %assetItem)
 {
    if(!isObject(%assetItem))

+ 13 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cpp.tscript

@@ -11,6 +11,19 @@ function AssetBrowser::buildCppPreview(%this, %assetDef, %previewData)
    %previewData.tooltip = %assetDef.assetName;
 }
 
+function AssetBrowser::buildCppAssetPreview(%this, %assetDef, %previewData)
+{
+   %previewData.assetName = %assetDef.assetName;
+   %previewData.assetPath = %assetDef.codeFilePath;
+   %previewData.doubleClickCommand = "echo(\"Not yet implemented to edit C++ files from the editor\");";//"EditorOpenFileInTorsion( "@%previewData.assetPath@", 0 );";
+   
+   %previewData.previewImage = "ToolsModule:cppIcon_image";
+   
+   %previewData.assetFriendlyName = %assetDef.assetName;
+   %previewData.assetDesc = %assetDef.description;
+   %previewData.tooltip = %assetDef.assetName;
+}
+
 function AssetBrowser::createCpp(%this)
 {
    %moduleName = AssetBrowser.newAssetSettings.moduleName;

+ 15 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/creatorObj.tscript

@@ -9,6 +9,14 @@ function AssetBrowser::buildCreatorPreview(%this, %assetDef, %previewData)
    
    %previewData.previewImage = "ToolsModule:" @ %class @ "_image";
    
+   if(!AssetDatabase.isDeclaredAsset(%previewData.previewImage))
+   {
+      if(EditorIsActive())
+         %previewData.previewImage = "ToolsModule:SceneObject_image";
+      else if(GuiEditorIsActive())
+         %previewData.previewImage = "ToolsModule:GuiControl_image";
+   }
+   
    //%previewData.assetFriendlyName = %assetDef.assetName;
    %previewData.assetDesc = %assetDef;
    %previewData.tooltip = "This creates a new object of the class " @ %class;
@@ -22,6 +30,8 @@ function AssetBrowser::onFinishCreateObject(%this, %objId)
 
 function AssetBrowser::onCreatorEditorDropped(%this, %assetDef, %position)
 {
+   if(EditorIsActive())
+   {
    %targetPosition = EWorldEditor.unproject(%position SPC 1000);
    %camPos = LocalClientConnection.camera.getPosition();
    %rayResult = containerRayCast(%camPos, %targetPosition, -1);
@@ -41,4 +51,9 @@ function AssetBrowser::onCreatorEditorDropped(%this, %assetDef, %position)
    
    %this.createdObjectPos = %pos;
    %newObj = eval(%func);
+   }
+   else if(GuiEditorIsActive())
+   {
+      %placeholderVar = "";
+   }
 }

+ 12 - 2
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript

@@ -434,9 +434,19 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData)
    %generatePreview = false;
 
    %previewFilePath = %previewPath @ %assetDef.assetName @ "_Preview.png";
-   if(!isFile(%previewFilePath) || (compareFileTimes(%assetDef.getImagePath(), %previewFilePath) == 1))
+   if(!isFile(%previewFilePath))
+   {
+      %generatePreview = true;
+   }
+   else
    {
+      if(isObject(%assetDef.materialDefinitionName))
+      {
+         if(compareFileTimes(%assetDef.materialDefinitionName.getDiffuseMap(0), %previewFilePath) == 1 ||
+            compareFileTimes(%assetDef.materialDefinitionName.getFilename(), %previewFilePath) == 1)
       %generatePreview = true;
+         
+      }
    }
 
    %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage";
@@ -479,7 +489,7 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData)
    
    //Revalidate. If it didn't work, just use the default placeholder one
    if(!isFile(%previewFilePath))
-      %previewAssetName = "ToolsModule:genericAssetIcon_image";
+      %previewAssetName = "ToolsModule:materialIcon_image";
       
    %previewData.assetName = %assetDef.assetName;
    %previewData.assetPath = %assetDef.scriptFile;

+ 1 - 1
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/prefab.tscript

@@ -21,7 +21,7 @@ function AssetBrowser::buildPrefabPreview(%this, %assetDef, %previewData)
    %previewData.assetName = %assetDef.assetName;
    %previewData.assetPath = %fullPath;
    
-   %previewData.previewImage = "ToolsModule:genericAssetIcon_image";
+   %previewData.previewImage = "ToolsModule:prefabIcon_image";
    
    //%previewData.assetFriendlyName = %assetDef.assetName;
    %previewData.assetDesc = %assetDef.description;

+ 16 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/script.tscript

@@ -90,6 +90,22 @@ function AssetBrowser::moveScriptAsset(%this, %assetDef, %destination)
    AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath);
 }
 
+function AssetBrowser::buildScriptAssetPreview(%this, %assetDef, %previewData)
+{
+   %previewData.assetName = %assetDef.assetName;
+   %previewData.assetPath = %assetDef.scriptFile;
+   %previewData.doubleClickCommand = "EditorOpenFileInTorsion( \""@%previewData.assetPath@"\", 0 );";
+   
+   if(%assetDef.isServerSide)
+      %previewData.previewImage = "ToolsModule:serverScriptIcon_image";
+   else
+      %previewData.previewImage = "ToolsModule:clientScriptIcon_image";
+   
+   %previewData.assetFriendlyName = %assetDef.assetName;
+   %previewData.assetDesc = %assetDef.description;
+   %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ "\nDefinition Path: " @ %assetDef.getFilename();
+}
+
 function AssetBrowser::buildTScriptPreview(%this, %assetDef, %previewData)
 {
    %previewData.assetName = %assetDef.assetName;

+ 6 - 5
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript

@@ -353,6 +353,7 @@ function AssetBrowser::onShapeAssetEditorDropped(%this, %assetDef, %position)
       
    EWorldEditor.isDirty = true;
    
+   MECreateUndoAction::submit(%newStatic );
 }
 
 function GuiInspectorTypeShapeAssetPtr::onControlDropped( %this, %payload, %position )
@@ -367,15 +368,15 @@ function GuiInspectorTypeShapeAssetPtr::onControlDropped( %this, %payload, %posi
    
    if(%assetType $= "ShapeAsset")
    {
-      //echo("DROPPED A SHAPE ON A SHAPE ASSET COMPONENT FIELD!");  
-      
       %module = %payload.moduleName;
       %asset = %payload.assetName;
       
-      %targetComponent = %this.targetObject;
-      %targetComponent.shapeAsset = %module @ ":" @ %asset;
+      %oldValue = %targetObject.shapeAsset;
+      %arrayIndex = "";
       
-      //Inspector.refresh();
+      %targetObject = %this.targetObject;
+      %targetObject.shapeAsset = %module @ ":" @ %asset;
+
    }
    
    EWorldEditor.isDirty = true;

+ 1 - 1
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrain.tscript

@@ -166,7 +166,7 @@ function AssetBrowser::buildTerrainAssetPreview(%this, %assetDef, %previewData)
    %previewData.assetName = %assetDef.assetName;
    %previewData.assetPath = "";
    
-   %previewData.previewImage = "ToolsModule:gameObjectIcon_image";
+   %previewData.previewImage = "ToolsModule:terrainIcon_image";
    
    %previewData.assetFriendlyName = %assetDef.gameObjectName;
    %previewData.assetDesc = %assetDef.description;

+ 194 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript

@@ -0,0 +1,194 @@
+function AssetBrowser::loadCreatorClasses(%this)
+{
+   // Just so we can recall this method for testing changes
+   // without restarting.
+   if ( isObject( %this.creatorClassArray ) )
+      %this.creatorClassArray.delete();
+      
+   AssetBrowserCreatorGroupsList.empty();
+      
+   %this.creatorClassArray = new ArrayObject();
+   %this.creatorClassArray.caseSensitive = true; 
+   //%this.setListView( true );
+   
+   //World Editor Creator Groups
+   %this.beginCreatorGroup( "Environment" );
+      %this.addCreatorClass( "BasicClouds",        "Basic Clouds" );
+      %this.addCreatorClass( "PxCloth",            "Cloth" );
+      %this.addCreatorClass( "CloudLayer",         "Cloud Layer" );
+      %this.addCreatorClass( "GroundCover",        "Ground Cover" );
+      %this.addCreatorClass( "Lightning" );
+      %this.addCreatorClass( "ParticleEmitterNode","Particle Emitter" );
+      %this.addCreatorClass( "Precipitation" );
+      // Legacy features. Users should use Ground Cover and the Forest Editor.   
+      //%this.addCreatorClass( "fxShapeReplicator",   "Shape Replicator" );
+      //%this.addCreatorClass( "fxFoliageReplicator", "Foliage Replicator" );
+      %this.addCreatorClass( "RibbonNode",         "Ribbon Emitter" );
+      %this.addCreatorClass( "ScatterSky",         "Scatter Sky" );
+      %this.addCreatorClass( "SkyBox",             "Sky Box" );
+      %this.addCreatorClass( "SFXEmitter",         "Sound Emitter" );
+      %this.addCreatorClass( "TerrainBlock",       "Terrain Block" );
+      %this.addCreatorClass( "VolumetricFog",      "Volumetric Fog" );
+      %this.addCreatorClass( "TimeOfDay",          "Time of Day" );
+      %this.addCreatorClass( "WaterBlock",         "Water Block" );
+      %this.addCreatorClass( "WaterPlane",         "Water Plane" );
+       %this.addCreatorClass( "ForestWindEmitter",  "Wind Emitter" );
+   %this.endCreatorGroup();
+   
+   %this.beginCreatorGroup( "ExampleObjects" );
+      %this.addCreatorClass( "RenderMeshExample" );
+      %this.addCreatorClass( "RenderObjectExample" );
+      %this.addCreatorClass( "RenderShapeExample" );
+   %this.endCreatorGroup(); 
+   
+   %this.beginCreatorGroup( "Level" );
+      %this.addCreatorClass("Camera" );
+      %this.addCreatorClass("GroundPlane",  "Ground Plane" );
+      %this.addCreatorClass("LevelInfo",    "Level Info" );
+      %this.addCreatorClass("Marker",       "Path Node" );
+      %this.addCreatorClass("MissionArea",  "Mission Area" );
+      %this.addCreatorClass("Note",         "Note" );
+      %this.addCreatorClass("Path" );
+      %this.addCreatorClass("SpawnSphere",  "General Spawn Sphere" );
+      %this.addCreatorClass("SpawnSphere",  "Player Spawn Sphere"/*, "PlayerDropPoint"*/ );
+      %this.addCreatorClass("SpawnSphere",  "Observer Spawn Sphere"/*, "ObserverDropPoint"*/ );
+      %this.addCreatorClass("VPath",        "Verve Path" );
+   %this.endCreatorGroup();
+   
+   %this.beginCreatorGroup( "Lighting" );
+      %this.addCreatorClass( "BoxEnvironmentProbe",      "Box Env. Probe" );
+      %this.addCreatorClass( "PointLight",               "Point Light" );
+      %this.addCreatorClass( "Skylight",                 "Skylight" );
+      %this.addCreatorClass( "SphereEnvironmentProbe",   "Sphere Env. Probe" );
+      %this.addCreatorClass( "SpotLight",                "Spot Light" );
+      %this.addCreatorClass( "Sun",                      "Basic Sun" );
+   %this.endCreatorGroup(); 
+
+   %this.beginCreatorGroup( "Navigation" );
+      %this.addCreatorClass( "AIPathGroup" );
+      %this.addCreatorClass( "CoverPoint",      "Cover Point" );
+      %this.addCreatorClass( "NavMesh",         "Navigation Mesh" );
+      %this.addCreatorClass( "NavPath",         "Navigation Path" );
+   %this.endCreatorGroup();  
+   
+   %this.beginCreatorGroup( "System" );
+      %this.addCreatorClass( "SimGroup" );
+   %this.endCreatorGroup();  
+   
+   %this.beginCreatorGroup( "Volumes" );
+      %this.addCreatorClass("AccumulationVolume",  "Accumulation Volume" );
+      %this.addCreatorClass("OcclusionVolume",     "Occlusion Volume" );
+      %this.addCreatorClass("PhysicalZone",        "Physical Zone" );
+      %this.addCreatorClass("Portal",              "Zone Portal" );
+      %this.addCreatorClass("SFXSpace",            "Sound Space" );
+      %this.addCreatorClass("Trigger" );
+      %this.addCreatorClass("Zone",                "Zone" );
+   %this.endCreatorGroup();  
+   
+   
+   
+   //Gui Editor Creator Groups
+   %controls = enumerateConsoleClassesByCategory( "Gui" );
+   %guiClasses = new ArrayObject();
+
+   foreach$( %className in %controls )
+   {
+      if( GuiEditor.isFilteredClass( %className )
+          || !isMemberOfClass( %className, "GuiControl" ) )
+         continue;
+         
+      %category = getWord( getCategoryOfClass( %className ), 1 );
+      if( %category $= "" )
+         continue;
+         
+      %guiClasses.add(%category, %className);
+   }
+   
+   %guiCats.sortk(true);
+   %guiClasses.sortk(true);
+   
+   %guiClasses.echo();
+   
+   %currentCat = "";
+   for(%i=0; %i < %guiClasses.count(); %i++)
+   {
+      %guiCat = %guiClasses.getKey(%i);
+      if(%currentCat !$= %guiCat)
+      {
+         if(%currentCat !$= "")
+            %this.endCreatorGroup(); 
+
+         %this.beginCreatorGroup( %guiCat, "GuiEditor" );
+         %currentCat = %guiCat;
+      }
+      
+      %guiClass = %guiClasses.getValue(%i);
+      %this.addCreatorClass( %guiClass );
+   }
+   
+   %this.endCreatorGroup(); 
+   
+   %this.creatorClassArray.sortk(true);
+   %this.creatorClassArray.sort(true);
+   
+   %guiClasses.delete();
+}
+
+function AssetBrowser::beginCreatorGroup(%this, %group, %editor)
+{
+   if(%editor $= "")
+      %editor = "WorldEditor";
+         
+   if((GuiEditorIsActive() && %editor $= "GuiEditor") || (EditorIsActive() && %editor $= "WorldEditor"))
+   {
+      AssetBrowser-->filterTree.insertItem(AssetBrowser-->filterTree.creatorIdx, %group);
+   }
+   
+   %this.currentCreatorGroup = %group;
+         
+   AssetBrowserCreatorGroupsList.add(%editor, %group);
+}
+
+function AssetBrowser::endCreatorGroup(%this, %group)
+{
+   %this.currentCreatorGroup = "";
+}
+
+function AssetBrowser::addCreatorClass(%this, %class, %name, %buildfunc)
+{
+   if( !isClass(%class) )
+      return;
+      
+   if ( %name $= "" )
+      %name = %class;
+      
+   if ( %this.currentCreatorGroup !$= "" && %group $= "" )
+      %group = %this.currentCreatorGroup;
+   
+   if ( %class $= "" || %group $= "" )
+   {
+      warn( "AssetBrowser::addCreatorClass, invalid parameters!" );
+      return;  
+   }
+   
+   if(%buildfunc $= "")
+   {
+      %method = "build" @ %buildfunc;
+      if( !ObjectBuilderGui.isMethod( %method ) )
+         %method = "build" @ %class;
+
+      if( !ObjectBuilderGui.isMethod( %method ) )
+         %cmd = "return new " @ %class @ "();";
+      else
+         %cmd = "ObjectBuilderGui." @ %method @ "();";
+
+      %buildfunc = "ObjectBuilderGui.newObjectCallback = \"AssetBrowser.onFinishCreateObject\"; EWCreatorWindow.createObject( \"" @ %cmd @ "\" );";
+   }
+   
+   %args = new ScriptObject();
+   %args.val[0] = %class;
+   %args.val[1] = %name;
+   %args.val[2] = %buildfunc;
+   
+   %this.creatorClassArray.push_back( %group, %args );
+}

+ 63 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/profiles.tscript

@@ -24,4 +24,67 @@ singleton GuiControlProfile(AssetBrowserPreviewShapeAsset : ToolsGuiDefaultProfi
    border = true;
    borderColor   = "0 0 200 255";
    borderColorNA = "0 0 200 255";
+};
+
+singleton GuiControlProfile(AssetBrowserPreviewShapeAnimationAsset : ToolsGuiDefaultProfile)
+{
+   fillColor = "128 128 128 255"; //hovered/selected
+   
+   border = true;
+   borderColor   = "0 0 200 255";
+   borderColorNA = "0 0 200 255";
+};
+
+singleton GuiControlProfile(AssetBrowserPreviewSoundAsset : ToolsGuiDefaultProfile)
+{
+   fillColor = "128 128 128 255"; //hovered/selected
+   
+   border = true;
+   borderColor   = "75 101 135 255";
+   borderColorNA = "75 101 135 255";
+};
+
+singleton GuiControlProfile(AssetBrowserPreviewTerrainAsset : ToolsGuiDefaultProfile)
+{
+   fillColor = "128 128 128 255"; //hovered/selected
+   
+   border = true;
+   borderColor   = "200 198 198 255";
+   borderColorNA = "200 198 198 255";
+};
+
+singleton GuiControlProfile(AssetBrowserPreviewTerrainMaterialAsset : ToolsGuiDefaultProfile)
+{
+   fillColor = "128 128 128 255"; //hovered/selected
+   
+   border = true;
+   borderColor   = "200 198 198 255";
+   borderColorNA = "200 198 198 255";
+};
+
+singleton GuiControlProfile(AssetBrowserPreviewStateMachineAsset : ToolsGuiDefaultProfile)
+{
+   fillColor = "128 128 128 255"; //hovered/selected
+   
+   border = true;
+   borderColor   = "0 76 135 255";
+   borderColorNA = "0 76 135 255";
+};
+
+singleton GuiControlProfile(AssetBrowserPreviewGUIAsset : ToolsGuiDefaultProfile)
+{
+   fillColor = "128 128 128 255"; //hovered/selected
+   
+   border = true;
+   borderColor   = "17 5 44 255";
+   borderColorNA = "17 5 44 255";
+};
+
+singleton GuiControlProfile(AssetBrowserPreviewLevelAsset : ToolsGuiDefaultProfile)
+{
+   fillColor = "128 128 128 255"; //hovered/selected
+   
+   border = true;
+   borderColor   = "0 208 186 255";
+   borderColorNA = "0 208 186 255";
 };

+ 5 - 0
Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript

@@ -289,6 +289,11 @@ function ESettingsWindow::getAxisSettings(%this)
 
 function ESettingsWindow::getGeneralSettings(%this)
 {
+   SettingsInspector.startGroup("Level Load");
+   SettingsInspector.addSettingsField("WorldEditor/LevelLoad/LoadMode", "Editor Startup Scene", "list", "When the editor loads, this setting dictates what scene is loaded first", 
+                                                                              "Last Edited Level,Editor Default Scene");
+   SettingsInspector.endGroup();
+   
    SettingsInspector.startGroup("Autosave");
    SettingsInspector.addSettingsField("WorldEditor/AutosaveInterval", "Autosave Interval(in minutes)", "int", "");
    SettingsInspector.endGroup();

+ 0 - 0
Templates/BaseGame/game/tools/gui/images/tab-border.png → Templates/BaseGame/game/tools/gui/images/tab_border.png


+ 1 - 1
Templates/BaseGame/game/tools/gui/images/tab_border_image.asset.taml

@@ -2,7 +2,7 @@
     canSave="true"
     canSaveDynamicFields="true"
     AssetName="tab_border_image"
-    imageFile="@assetFile=tab-border.png"
+    imageFile="@assetFile=tab_border.png"
     UseMips="true"
     isHDRImage="false"
     imageType="Albedo" />

+ 12 - 3
Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.tscript

@@ -670,16 +670,21 @@ function GuiEditor::onControlDropped(%this, %payload, %position)
 {  
    // Make sure we have the right kind of D&D.
    
-   if( !%payload.parentGroup.isInNamespaceHierarchy( "GuiDragAndDropControlType_GuiControl" ) )
+   if( !%payload.parentGroup.isInNamespaceHierarchy( "GuiDragAndDropControlType_GuiControl" ) &&
+         !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ))
       return;
 
    %pos = %payload.getGlobalPosition();
    %x = getWord(%pos, 0);
    %y = getWord(%pos, 1);
 
-   %this.addNewCtrl(%payload);
+   %asset = %payload.assetName;
+   %cmd = "return new " @ %asset @ "();";
+   %ctrl = eval( %cmd );
+
+   %this.addNewCtrl(%ctrl);
    
-   %payload.setPositionGlobal(%x, %y);
+   %ctrl.setPositionGlobal(%x, %y);
    %this.setFirstResponder();
 }
 
@@ -844,6 +849,8 @@ function GuiEditorTabBook::onWake( %this )
          item[ 0 ] = "Alphabetical View" TAB "" TAB "GuiEditorToolbox.setViewType( \"Alphabetical\" );";
          item[ 1 ] = "Categorized View" TAB "" TAB "GuiEditorToolbox.setViewType( \"Categorized\" );";
       };
+      
+   GlobalActionMap.bindCmd( keyboard, space, "", "AssetBrowser.toggleDialog();" );
 }
 
 //---------------------------------------------------------------------------------------------
@@ -1008,6 +1015,8 @@ function GuiEditorGui::onWake( %this )
 
 function GuiEditorGui::onSleep( %this)
 {
+   GlobalActionMap.unbind( keyboard, space );
+   
    // If we are editing a control, store its guide state.
    
    %content = GuiEditor.getContentControl();

+ 28 - 0
Templates/BaseGame/game/tools/main.tscript

@@ -278,7 +278,35 @@ function fastLoadWorldEdit(%val)
          
       if( !$missionRunning )
       {
+         if(EditorSettings.value("WorldEditor/LevelLoad/LoadMode", "Editor Default Scene") $= "Editor Default Scene")
+         {
          EditorNewLevel("ToolsModule:DefaultEditorLevel");
+         }
+         else
+         {
+            //go back through our recent levels list to find the most recent valid editor level.
+            //if NONE work, then just load the default editor scene
+            %recentLevels = EditorSettings.value("WorldEditor/recentLevelsList");
+            %recentCount = getTokenCount(%recentLevels, ",");
+            %loadedScene = false;
+            
+            for(%i=0; %i < %recentCount; %i++)
+            {
+               %recentEntry = getToken(%recentLevels, ",", %i);
+               
+               if(AssetDatabase.isDeclaredAsset(%recentEntry))
+               {
+                  EditorOpenMission(%recentEntry);
+                  %loadedScene = true;
+                  break;
+               }
+            }
+            
+            if(!%loadedScene)
+            {
+               EditorNewLevel("ToolsModule:DefaultEditorLevel");
+            }
+         }
       }
       else
       {

+ 3 - 3
Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript

@@ -315,7 +315,7 @@ function ShapeEditor::selectShape( %this, %shapeAsset, %saveOld )
    ShapeEditor.shape = findShapeConstructorByAssetId( %shapeAsset.getAssetId() );
    if ( ShapeEditor.shape <= 0 )
    {
-      ShapeEditor.shape = %this.createConstructor( %shapeAsset );
+      ShapeEditor.shape = %this.createConstructor( %shapeAsset.getAssetId() );
       if ( ShapeEditor.shape <= 0 )
       {
          error( "ShapeEditor: Error - could not select " @ %shapeAsset.getAssetId() );
@@ -2336,7 +2336,7 @@ function ShapeEdMaterials::updateSelectedMaterial( %this, %highlight )
    %this.savedMap = %this.selectedMaterial.diffuseMap[1];
    if ( %highlight && isObject( %this.selectedMaterial ) )
    {
-      %this.selectedMaterial.diffuseMap[1] = "tools/shapeEditor/images/highlight_material";
+      %this.selectedMaterial.setDiffuseMap("ToolsModule:highlight_material_image", 1);
       %this.selectedMaterial.reload();
    }
 }
@@ -3066,7 +3066,7 @@ function ShapeEditor::addLODFromFile( %this, %dest, %assetId, %size, %allowUnmat
 
    %source = findShapeConstructorByAssetId( %assetId );
    if ( %source == -1 )
-      %source = ShapeEditor.createConstructor( %filename );
+      %source = ShapeEditor.createConstructor( %assetId  );
    %source.lodType = "SingleSize";
    %source.singleDetailSize = %size;