Pārlūkot izejas kodu

Implements shape preview caching for shape assets
Also standardizes the loading gui overlay so it can be used to inform that the asset preview generation is happening

Areloch 4 gadi atpakaļ
vecāks
revīzija
85a9a9b608

+ 42 - 7
Engine/source/T3D/assets/ShapeAsset.cpp

@@ -46,6 +46,10 @@
 #include "platform/profiler.h"
 #include "T3D/assets/assetImporter.h"
 
+#ifdef TORQUE_TOOLS
+#include "ts/tsLastDetail.h"
+#endif
+
 //-----------------------------------------------------------------------------
 
 IMPLEMENT_CONOBJECT(ShapeAsset);
@@ -505,6 +509,29 @@ ShapeAnimationAsset* ShapeAsset::getAnimation(S32 index)
    return nullptr;
 }
 
+#ifdef TORQUE_TOOLS
+const char* ShapeAsset::generateCachedPreviewImage(S32 resolution)
+{
+   if (!mShape)
+      return "";
+
+   TSLastDetail* dt = new TSLastDetail(mShape,
+      mFilePath,
+      1,
+      0,
+      0,
+      false,
+      0,
+      resolution);
+
+   dt->update();
+
+   delete dt;
+
+   return mFilePath;
+}
+#endif
+
 DefineEngineMethod(ShapeAsset, getMaterialCount, S32, (), ,
    "Gets the number of materials for this shape asset.\n"
    "@return Material count.\n")
@@ -526,6 +553,21 @@ DefineEngineMethod(ShapeAsset, getAnimation, ShapeAnimationAsset*, (S32 index),
 {
    return object->getAnimation(index);
 }
+
+DefineEngineMethod(ShapeAsset, getShapeFile, const char*, (), ,
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->getShapeFilePath();
+}
+
+#ifdef TORQUE_TOOLS
+DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution), (256), "")
+{
+   return object->generateCachedPreviewImage(resolution);
+}
+#endif
+
 //-----------------------------------------------------------------------------
 // GuiInspectorTypeAssetId
 //-----------------------------------------------------------------------------
@@ -625,10 +667,3 @@ void GuiInspectorTypeShapeAssetId::consoleInit()
 }
 
 #endif
-
-DefineEngineMethod(ShapeAsset, getShapeFile, const char*, (), ,
-   "Creates a new script asset using the targetFilePath.\n"
-   "@return The bool result of calling exec")
-{
-   return object->getShapeFilePath();
-}

+ 4 - 0
Engine/source/T3D/assets/ShapeAsset.h

@@ -165,6 +165,10 @@ public:
 
    static StringTableEntry getNoShapeAssetId() { return StringTable->insert("Core_Rendering:noshape"); }
 
+#ifdef TORQUE_TOOLS
+   const char* generateCachedPreviewImage(S32 resolution);
+#endif
+
 protected:
    virtual void            onAssetRefresh(void);
 

+ 2 - 3
Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.tscript

@@ -983,8 +983,7 @@ function ImportAssetWindow::ImportAssets(%this)
          return;
       }
       
-      Canvas.pushDialog( EditorLoadingGui );
-      Canvas.repaint();
+      displayEditorLoadingGui("Importing Assets...");
    
       %this.importer.targetModuleId = %moduleName;
    }
@@ -1000,7 +999,7 @@ function ImportAssetWindow::ImportAssets(%this)
    
    %this.importer.resetImportSession(true);
    
-   Canvas.popDialog( EditorLoadingGui );
+   hideEditorLoadingGui();
    
    //do the actual importing, now!
    /*%assetCount = ImportAssetItems.count();

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

@@ -244,10 +244,48 @@ function AssetBrowser::importShapeAsset(%this, %assetItem)
 
 function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData)
 {
+   %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(%assetDef.getShapeFile())));
+   %previewPath = "tools/resources/shapePreviewCache/" @ %module.moduleId @ "/";
+   
+   if(!IsDirectory(%previewPath))
+   {
+      %this.dirHandler.createFolder(%previewPath);
+   }
+   
+   %previewPath = %previewPath @ %assetDef.assetName @ "_Preview.png";
+   if(!isFile(%previewPath))
+   {
+      displayEditorLoadingGui("Generating Shape Asset Preview...");
+      
+      //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
+      %oldImposterSetting = $TSLastDetail::dumpImposters;
+      $TSLastDetail::dumpImposters = true;
+      
+      %filePath = %assetDef.generateCachedPreviewImage();
+      
+      %imposterPath = %filePath @ ".imposter.png";
+      pathCopy(%imposterPath, %previewPath);
+      
+      //cleanup
+      fileDelete(%imposterPath);
+      fileDelete(%filePath @ ".imposter.dds");
+      fileDelete(%filePath @ ".imposter_normals.png");
+      fileDelete(%filePath @ ".imposter_normals.dds");
+      
+      $TSLastDetail::dumpImposters = %oldImposterSetting;
+      
+      hideEditorLoadingGui();
+   }
+   
+   //Revalidate. If it didn't work, just use the default placeholder one
+   if(!isFile(%previewPath))
+      %previewPath = "tools/assetBrowser/art/genericAssetIcon";
+   
    %previewData.assetName = %assetDef.assetName;
    %previewData.assetPath = %assetDef.fileName;
 
-   %previewData.previewImage = "tools/assetBrowser/art/genericAssetIcon";//%assetDef.fileName;
+   %previewData.previewImage = %previewPath;//%assetDef.fileName;
    
    %previewData.assetFriendlyName = %assetDef.assetName;
    %previewData.assetDesc = %assetDef.description;

+ 17 - 0
Templates/BaseGame/game/tools/gui/EditorLoadingGui.gui

@@ -52,6 +52,7 @@
          isContainer = "0";
          canSave = "1";
          canSaveDynamicFields = "0";
+         internalName = "loadingText";
       };
    };
 };
@@ -73,3 +74,19 @@ function EditorLoadingGui::onWake(%this)
    %posY = (%resY / 2) - (%dialogHeight / 2);
    %dialog.setPosition(%posX, %posY);
 }
+
+function displayEditorLoadingGui(%displayText)
+{
+   if(%displayText $= "")
+      %displayText = "Loading the Editor...";
+      
+   EditorLoadingGui-->loadingText.setText(%displayText);
+   
+   Canvas.pushDialog( EditorLoadingGui );
+   Canvas.repaint();
+}
+
+function hideEditorLoadingGui()
+{
+   Canvas.popDialog( EditorLoadingGui );
+}

+ 6 - 9
Templates/BaseGame/game/tools/main.tscript

@@ -261,12 +261,11 @@ function fastLoadWorldEdit(%val)
    {
       if(!$Tools::loaded)
       {
-         canvas.pushDialog( EditorLoadingGui );
-         canvas.repaint();
+         displayEditorLoadingGui();
       
          onStart();
          
-         canvas.popDialog(EditorLoadingGui);
+         hideEditorLoadingGui();
       }
       
       %timerId = startPrecisionTimer();
@@ -304,8 +303,7 @@ function fastLoadWorldEdit(%val)
          }
          else
          {
-            canvas.pushDialog( EditorLoadingGui );
-            canvas.repaint();
+            displayEditorLoadingGui();
       
             Editor.open();
 			
@@ -317,7 +315,7 @@ function fastLoadWorldEdit(%val)
             if (theLevelInfo.type $= "DemoScene")
                commandToServer('dropCameraAtPlayer', true);
                
-            canvas.popDialog(EditorLoadingGui);
+            hideEditorLoadingGui();
          }
          
          popInstantGroup();
@@ -334,12 +332,11 @@ function fastLoadGUIEdit(%val)
    {
       if(!$Tools::loaded)
       {
-         canvas.pushDialog( EditorLoadingGui );
-         canvas.repaint();
+         displayEditorLoadingGui();
       
          onStart();
          
-         canvas.popDialog(EditorLoadingGui);
+         hideEditorLoadingGui();
       }
 
       toggleGuiEditor(true);

+ 2 - 3
Templates/BaseGame/game/tools/worldEditor/scripts/editor.ed.tscript

@@ -138,8 +138,7 @@ function toggleEditor(%make)
          }
          else
          {
-            canvas.pushDialog( EditorLoadingGui );
-            canvas.repaint();
+            displayEditorLoadingGui();
             
             Editor.open();
 			
@@ -151,7 +150,7 @@ function toggleEditor(%make)
             if (theLevelInfo.type $= "DemoScene")
                commandToServer('dropCameraAtPlayer', true);
                
-            canvas.popDialog(EditorLoadingGui);
+            hideEditorLoadingGui();
          }
          
          popInstantGroup();