Procházet zdrojové kódy

Merge pull request #434 from Areloch/UpdatedCppAssets

Adjusts handling of C++ asset types
Brian Roberts před 4 roky
rodič
revize
ab4c19e5ff

+ 106 - 11
Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs

@@ -333,17 +333,7 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName )
       //special-case entry
       //special-case entry
       if(getFieldCount(%asset) > 1)
       if(getFieldCount(%asset) > 1)
       {
       {
-         %specialType = getField(%asset,0);
-         
-         /*if(%specialType $= "Folder")
-         {
-            
-         }
-         else if(%specialType $= "Datablock")
-         {
-            %sdfasdgah = true;  
-         }*/
-         %assetType = %specialType;
+         %assetType = getField(%asset,0);
          %assetName = getField(%asset, 1);
          %assetName = getField(%asset, 1);
          %sdfasdgah = true;  
          %sdfasdgah = true;  
          
          
@@ -389,6 +379,38 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName )
             %fullPath = strreplace(%fullPath, "/", "_");
             %fullPath = strreplace(%fullPath, "/", "_");
             %fullPath = strreplace(%fullPath, ".", "-");
             %fullPath = strreplace(%fullPath, ".", "-");
             
             
+            if(isObject(%fullPath))
+               %assetDesc = %fullPath;
+            else
+               %assetDesc = new ScriptObject(%fullPath);
+               
+            %assetDesc.dirPath = %moduleName;
+            %assetDesc.assetName = %assetName;
+            %assetDesc.description = %moduleName @ "/" @ %assetName;
+            %assetDesc.assetType = %assetType;
+         }
+         else if(%assetType $= "Cpp")
+         {
+            %fullPath = %moduleName !$= "" ? %moduleName @ "/" @ %assetName : %assetName;
+            %fullPath = strreplace(%fullPath, "/", "_");
+            %fullPath = strreplace(%fullPath, ".", "-");
+            
+            if(isObject(%fullPath))
+               %assetDesc = %fullPath;
+            else
+               %assetDesc = new ScriptObject(%fullPath);
+               
+            %assetDesc.dirPath = %moduleName;
+            %assetDesc.assetName = %assetName;
+            %assetDesc.description = %moduleName @ "/" @ %assetName;
+            %assetDesc.assetType = %assetType;
+         }
+         else if(%assetType $= "tscript")
+         {
+            %fullPath = %moduleName !$= "" ? %moduleName @ "/" @ %assetName : %assetName;
+            %fullPath = strreplace(%fullPath, "/", "_");
+            %fullPath = strreplace(%fullPath, ".", "-");
+            
             if(isObject(%fullPath))
             if(isObject(%fullPath))
                %assetDesc = %fullPath;
                %assetDesc = %fullPath;
             else
             else
@@ -1568,6 +1590,7 @@ function AssetBrowser::doRebuildAssetArray(%this)
          %looseFileFullPath = ABLooseFileArray.getKey(%i);
          %looseFileFullPath = ABLooseFileArray.getKey(%i);
          %looseFilePath = filePath(%looseFileFullPath);
          %looseFilePath = filePath(%looseFileFullPath);
          %looseFileName = fileName(%looseFileFullPath);
          %looseFileName = fileName(%looseFileFullPath);
+         %looseFileExt = fileExt(%looseFileFullPath);
          
          
          %assetArray.add( %looseFilePath, "LooseFile" TAB %looseFileName );
          %assetArray.add( %looseFilePath, "LooseFile" TAB %looseFileName );
       }
       }
@@ -1599,6 +1622,78 @@ function AssetBrowser::doRebuildAssetArray(%this)
 
 
          %fullPrefabPath = findNextFile( %breadcrumbPath @ "/" @ %expr );
          %fullPrefabPath = findNextFile( %breadcrumbPath @ "/" @ %expr );
       }
       }
+      
+      //C++ files
+      %cppPattern = %breadcrumbPath @ "/" @ "*.cpp";
+      for (%fullCppPath = findFirstFile(%cppPattern); %fullCppPath !$= ""; %fullCppPath = findNextFile(%cppPattern))
+      {
+         %cppPath = filePath(%fullCppPath);
+         %cppName = fileName(%fullCppPath);
+         
+         %searchActive = AssetSearchTerms.count() != 0;
+         if(%searchActive)
+         {
+            if(startsWith(%cppPath, %breadcrumbPath))
+            {
+               if(matchesSearch(%cppName, "Cpp"))
+               {
+                  %assetArray.add( %cppPath, "Cpp" TAB %cppName );
+               }  
+            }
+         }
+         else if(%cppPath $= %breadcrumbPath)
+         {
+            %assetArray.add( %cppPath, "Cpp" TAB %cppName );
+         }
+      }
+      
+      //C++ Header files
+      %cppPattern = %breadcrumbPath @ "/" @ "*.h";
+      for (%fullCppPath = findFirstFile(%cppPattern); %fullCppPath !$= ""; %fullCppPath = findNextFile(%cppPattern))
+      {
+         %cppPath = filePath(%fullCppPath);
+         %cppName = fileName(%fullCppPath);
+         
+         %searchActive = AssetSearchTerms.count() != 0;
+         if(%searchActive)
+         {
+            if(startsWith(%cppPath, %breadcrumbPath))
+            {
+               if(matchesSearch(%cppName, "Cpp"))
+               {
+                  %assetArray.add( %cppPath, "Cpp" TAB %cppName );
+               }  
+            }
+         }
+         else if(%cppPath $= %breadcrumbPath)
+         {
+            %assetArray.add( %cppPath, "Cpp" TAB %cppName );
+         }
+      }
+      
+      //script files
+      %tscriptPattern = %breadcrumbPath @ "/" @ "*.tscript";
+      for (%fullScriptPath = findFirstFile(%tscriptPattern); %fullScriptPath !$= ""; %fullScriptPath = findNextFile(%tscriptPattern))
+      {
+         %tscriptPath = filePath(%fullScriptPath);
+         %tscriptName = fileName(%fullScriptPath);
+         
+         %searchActive = AssetSearchTerms.count() != 0;
+         if(%searchActive)
+         {
+            if(startsWith(%tscriptPath, %breadcrumbPath))
+            {
+               if(matchesSearch(%tscriptName, "tscript"))
+               {
+                  %assetArray.add( %tscriptPath, "tscript" TAB %tscriptName );
+               }  
+            }
+         }
+         else if(%tscriptPath $= %breadcrumbPath)
+         {
+            %assetArray.add( %tscriptPath, "tscript" TAB %tscriptName );
+         }
+      }
    }
    }
 	
 	
    for(%i=0; %i < %assetArray.count(); %i++)
    for(%i=0; %i < %assetArray.count(); %i++)

+ 42 - 29
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cpp.cs

@@ -1,4 +1,4 @@
-function AssetBrowser::buildCppAssetPreview(%this, %assetDef, %previewData)
+function AssetBrowser::buildCppPreview(%this, %assetDef, %previewData)
 {
 {
    %previewData.assetName = %assetDef.assetName;
    %previewData.assetName = %assetDef.assetName;
    %previewData.assetPath = %assetDef.codeFilePath;
    %previewData.assetPath = %assetDef.codeFilePath;
@@ -11,7 +11,7 @@ function AssetBrowser::buildCppAssetPreview(%this, %assetDef, %previewData)
    %previewData.tooltip = %assetDef.assetName;
    %previewData.tooltip = %assetDef.assetName;
 }
 }
 
 
-function AssetBrowser::createCppAsset(%this)
+function AssetBrowser::createCpp(%this)
 {
 {
    %moduleName = AssetBrowser.newAssetSettings.moduleName;
    %moduleName = AssetBrowser.newAssetSettings.moduleName;
    %modulePath = "data/" @ %moduleName;
    %modulePath = "data/" @ %moduleName;
@@ -20,21 +20,12 @@ function AssetBrowser::createCppAsset(%this)
    
    
    %assetPath = AssetBrowser.dirHandler.currentAddress @ "/";     
    %assetPath = AssetBrowser.dirHandler.currentAddress @ "/";     
    
    
-   %tamlpath = %assetPath @ %assetName @ ".asset.taml";
+   //%tamlpath = %assetPath @ %assetName @ ".asset.taml";
    %codePath = %assetPath @ %assetName @ ".cpp";
    %codePath = %assetPath @ %assetName @ ".cpp";
    %headerPath = %assetPath @ %assetName @ ".h";
    %headerPath = %assetPath @ %assetName @ ".h";
    
    
    //Do the work here
    //Do the work here
-   %assetType = AssetBrowser.newAssetSettings.assetType;
-   
-   /*if(%assetType $= "CppStaticClassAsset" 
-	   || %assetType $= "CppRegularClassAsset" 
-	   || %assetType $= "CppGameObjectAsset"
-	   || %assetType $= "CppComponentAsset"
-      || %assetType $= "CppScriptClass")
-   {
-      
-   }*/
+   /*%assetType = AssetBrowser.newAssetSettings.assetType;
    
    
    %asset = new CppAsset()
    %asset = new CppAsset()
    {
    {
@@ -44,26 +35,48 @@ function AssetBrowser::createCppAsset(%this)
       headerFile = %headerPath;
       headerFile = %headerPath;
    };
    };
    
    
-   TamlWrite(%asset, %tamlpath);
+   TamlWrite(%asset, %tamlpath);*/
    
    
    %moduleDef = ModuleDatabase.findModule(%moduleName, 1);
    %moduleDef = ModuleDatabase.findModule(%moduleName, 1);
 	AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath);
 	AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath);
 
 
-	AssetBrowser.loadFilters();
+	//AssetBrowser.loadFilters();
 	
 	
-	%treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName);
+	/*%treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName);
 	%smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "CppAsset");
 	%smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "CppAsset");
 	
 	
-	AssetBrowserFilterTree.onSelect(%smItem);
+	AssetBrowserFilterTree.onSelect(%smItem);*/
 	
 	
 	%file = new FileObject();
 	%file = new FileObject();
 	%templateFile = new FileObject();
 	%templateFile = new FileObject();
 	
 	
-	if(%assetType $= "CppStaticClassAsset")
+	if($AssetBrowser::newAssetTypeOverride $= "StaticClass")
+	{
+	   %cppTemplateCodeFilePath = %this.templateFilesPath @ "CppStaticClassFile.cpp.template";
+	   %cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppStaticClassFile.h.template";
+	}
+	else if($AssetBrowser::newAssetTypeOverride $= "ScriptClass")
+	{
+	   %cppTemplateCodeFilePath = %this.templateFilesPath @ "CppScriptClassFile.cpp.template";
+	   %cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppScriptClassFile.h.template";
+	}
+	else if($AssetBrowser::newAssetTypeOverride $= "AssetTypeCppClass")
+	{
+	   %cppTemplateCodeFilePath = %this.templateFilesPath @ "CppAssetTypeClassFile.cpp.template";
+	   %cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppAssetTypeClassFile.h.template";
+	}
+	else if($AssetBrowser::newAssetTypeOverride $= "RenderCppClass")
 	{
 	{
-	   %cppTemplateCodeFilePath = %this.templateFilesPath @ "CppStaticClassFile.cpp";
-	   %cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppStaticClassFile.h";
+	   %cppTemplateCodeFilePath = %this.templateFilesPath @ "CppRenderClassFile.cpp.template";
+	   %cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppRenderClassFile.h.template";
 	}
 	}
+	else if($AssetBrowser::newAssetTypeOverride $= "SceneObjectCppClass")
+	{
+	   %cppTemplateCodeFilePath = %this.templateFilesPath @ "CppSceneObjectClassFile.cpp.template";
+	   %cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppSceneObjectClassFile.h.template";
+	}
+	
+	$AssetBrowser::newAssetTypeOverride = "";
    
    
    if(%file.openForWrite(%codePath) && %templateFile.openForRead(%cppTemplateCodeFilePath))
    if(%file.openForWrite(%codePath) && %templateFile.openForRead(%cppTemplateCodeFilePath))
    {
    {
@@ -73,7 +86,7 @@ function AssetBrowser::createCppAsset(%this)
          %line = strreplace( %line, "@", %assetName );
          %line = strreplace( %line, "@", %assetName );
          
          
          %file.writeline(%line);
          %file.writeline(%line);
-         echo(%line);
+         //echo(%line);
       }
       }
       
       
       %file.close();
       %file.close();
@@ -84,7 +97,7 @@ function AssetBrowser::createCppAsset(%this)
       %file.close();
       %file.close();
       %templateFile.close();
       %templateFile.close();
       
       
-      warnf("CreateNewCppAsset - Something went wrong and we couldn't write the C++ code file!");
+      warn("CreateNewCppAsset - Something went wrong and we couldn't write the C++ code file!");
    }
    }
    
    
    if(%file.openForWrite(%headerPath) && %templateFile.openForRead(%cppTemplateHeaderFilePath))
    if(%file.openForWrite(%headerPath) && %templateFile.openForRead(%cppTemplateHeaderFilePath))
@@ -95,7 +108,7 @@ function AssetBrowser::createCppAsset(%this)
          %line = strreplace( %line, "@", %assetName );
          %line = strreplace( %line, "@", %assetName );
          
          
          %file.writeline(%line);
          %file.writeline(%line);
-         echo(%line);
+         //echo(%line);
       }
       }
       
       
       %file.close();
       %file.close();
@@ -124,7 +137,7 @@ function AssetBrowser::createCppAsset(%this)
             %line = strreplace( %line, "@", %moduleName );
             %line = strreplace( %line, "@", %moduleName );
             
             
             %file.writeline(%line);
             %file.writeline(%line);
-            echo(%line);
+            //echo(%line);
          }
          }
          
          
          %file.close();
          %file.close();
@@ -139,15 +152,15 @@ function AssetBrowser::createCppAsset(%this)
       }
       }
 	}
 	}
    
    
-	return %tamlpath;
+	return "";
 }
 }
 
 
-function AssetBrowser::editCppAsset(%this, %assetDef)
+function AssetBrowser::editCpp(%this, %assetDef)
 {
 {
 }
 }
 
 
 //Renames the asset
 //Renames the asset
-function AssetBrowser::renameCppAsset(%this, %assetDef, %newAssetName)
+function AssetBrowser::renameCpp(%this, %assetDef, %newAssetName)
 {
 {
    %newCodeLooseFilename = renameAssetLooseFile(%assetDef.codefile, %newAssetName);
    %newCodeLooseFilename = renameAssetLooseFile(%assetDef.codefile, %newAssetName);
    
    
@@ -167,13 +180,13 @@ function AssetBrowser::renameCppAsset(%this, %assetDef, %newAssetName)
 }
 }
 
 
 //Deletes the asset
 //Deletes the asset
-function AssetBrowser::deleteCppAsset(%this, %assetDef)
+function AssetBrowser::deleteCpp(%this, %assetDef)
 {
 {
    AssetDatabase.deleteAsset(%assetDef.getAssetId(), true);
    AssetDatabase.deleteAsset(%assetDef.getAssetId(), true);
 }
 }
 
 
 //Moves the asset to a new path/module
 //Moves the asset to a new path/module
-function AssetBrowser::moveCppAsset(%this, %assetDef, %destination)
+function AssetBrowser::moveCpp(%this, %assetDef, %destination)
 {
 {
    %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId());
    %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId());
    %targetModule = AssetBrowser.getModuleFromAddress(%destination);
    %targetModule = AssetBrowser.getModuleFromAddress(%destination);

+ 5 - 7
Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.cs

@@ -154,13 +154,11 @@ function AssetBrowser::buildPopupMenus(%this)
          class = "EditorWorldMenu";
          class = "EditorWorldMenu";
          //isPopup = true;
          //isPopup = true;
 
 
-         /*item[ 0 ] = "Create Static Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppStaticClassAsset\", AssetBrowser.selectedModule);";
-         item[ 1 ] = "Create Regular Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppRegularClassAsset\", AssetBrowser.selectedModule);";
-         item[ 2 ] = "Create GameObject Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppGameObjectAsset\", AssetBrowser.selectedModule);";
-         item[ 3 ] = "Create Component Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppComponentAsset\", AssetBrowser.selectedModule);";
-         item[ 4 ] = "Create Script Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppScriptClass\", AssetBrowser.selectedModule);";*/
-         
-         item[ 0 ] = "Create C++ Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
+         item[ 0 ] = "Create Static C++ Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"StaticClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
+         item[ 1 ] = "Create ScriptObject C++ Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"ScriptClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
+         item[ 2 ] = "Create AssetType C++ Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"AssetTypeCppClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
+         item[ 3 ] = "Create Render C++ Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"RenderCppClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
+         item[ 3 ] = "Create SceneObject Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"SceneObjectCppClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
       };
       };
       //%this.AddNewScriptAssetPopup.insertSubMenu(0, "Create Component", AddNewComponentAssetPopup);
       //%this.AddNewScriptAssetPopup.insertSubMenu(0, "Create Component", AddNewComponentAssetPopup);
    }
    }

+ 409 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/CppAssetTypeClassFile.cpp.template

@@ -0,0 +1,409 @@
+#ifndef @_H_
+#include "@.h"
+#endif
+
+#ifndef _ASSET_MANAGER_H_
+#include "assets/assetManager.h"
+#endif
+
+#ifndef _CONSOLETYPES_H_
+#include "console/consoleTypes.h"
+#endif
+
+#ifndef _TAML_
+#include "persistence/taml/taml.h"
+#endif
+
+#ifndef _ASSET_PTR_H_
+#include "assets/assetPtr.h"
+#endif
+
+#include "core/resourceManager.h"
+
+// Debug Profiling.
+#include "platform/profiler.h"
+#include "T3D/assets/assetImporter.h"
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_CONOBJECT(@);
+
+ConsoleType(assetIdString, Type@Ptr, String, ASSET_ID_FIELD_PREFIX)
+
+ConsoleGetType(Type@Ptr)
+{
+   // Fetch asset Id.
+   //return *((StringTableEntry*)dptr);
+   return (*((AssetPtr<@>*)dptr)).getAssetId();
+}
+
+ConsoleSetType(Type@Ptr)
+{
+   // Was a single argument specified?
+   if (argc == 1)
+   {
+      // Yes, so fetch field value.
+      const char* pFieldValue = argv[0];
+
+      // Fetch asset Id.
+      StringTableEntry* assetId = (StringTableEntry*)(dptr);
+
+      // Update asset value.
+      *assetId = StringTable->insert(pFieldValue);
+
+      return;
+   }
+
+   // Warn.
+   Con::warnf("(TypeAssetId) - Cannot set multiple args to a single asset.");
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleType(assetIdString, Type@Id, String, ASSET_ID_FIELD_PREFIX)
+
+ConsoleGetType(Type@Id)
+{
+   // Fetch asset Id.
+   return *((const char**)(dptr));
+}
+
+ConsoleSetType(Type@Id)
+{
+   // Was a single argument specified?
+   if (argc == 1)
+   {
+      // Yes, so fetch field value.
+      const char* pFieldValue = argv[0];
+
+      // Fetch asset Id.
+      StringTableEntry* assetId = (StringTableEntry*)(dptr);
+
+      // Update asset value.
+      *assetId = StringTable->insert(pFieldValue);
+
+      return;
+   }
+
+   // Warn.
+   Con::warnf("(TypeAssetId) - Cannot set multiple args to a single asset.");
+}
+
+//-----------------------------------------------------------------------------
+
+const String @::mErrCodeStrings[] =
+{
+   "UnKnown"
+};
+//-----------------------------------------------------------------------------
+
+@::@()
+{
+   mFileName = StringTable->EmptyString();
+   mFilePath = StringTable->EmptyString();
+   mLoadedState = AssetErrCode::NotLoaded;
+}
+
+//-----------------------------------------------------------------------------
+
+@::~@()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+void @::initPersistFields()
+{
+   // Call parent.
+   Parent::initPersistFields();
+
+   addProtectedField("fileName", TypeAssetLooseFilePath, Offset(mFileName, @),
+      &set@File, &get@File, "Path to the asset file");
+}
+
+// In the event we have any special case logic where the asset's values are changed(such as a dependency value is updated), this
+// will let us react to that variable changing to implement behavior in response
+void @::setDataField(StringTableEntry slotName, const char *array, const char *value)
+{
+   Parent::setDataField(slotName, array, value);
+}
+
+void @::initializeAsset()
+{
+   // Call parent.
+   Parent::initializeAsset();
+
+   if (mFileName == StringTable->EmptyString())
+      return;
+
+   ResourceManager::get().getChangedSignal().notify(this, &@::_onResourceChanged);
+
+   //Ensure our path is expando'd if it isn't already
+   if (!Platform::isFullPath(mFilePath))
+      mFilePath = getOwned() ? expandAssetFilePath(mFileName) : mFilePath;
+
+   //Do a loading function here to do the actual load logic
+}
+
+void @::set@File(const char* pFile)
+{
+   // Sanity!
+   AssertFatal(pFile != NULL, "Cannot use a NULL file.");
+
+   // Fetch file.
+   pFile = StringTable->insert(pFile);
+
+   // Ignore no change,
+   if (pFile == mFileName)
+      return;
+
+   mFileName = pFile;
+
+   // Refresh the asset.
+   refreshAsset();
+}
+
+void @::_onResourceChanged(const Torque::Path &path)
+{
+   if (path != Torque::Path(mFilePath) )
+      return;
+
+   refreshAsset();
+
+   //Do a loading function here to do the actual load logic
+}
+
+//------------------------------------------------------------------------------
+//Utility function to 'fill out' bindings and resources with a matching asset if one exists
+bool @::getAssetByFilename(StringTableEntry fileName, AssetPtr<@>* @)
+{
+   AssetQuery query;
+   S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
+   if (foundAssetcount == 0)
+   {
+      //Didn't find any assets
+      //If possible, see if we can run an in-place import and the get the asset from that
+#if TORQUE_DEBUG
+      Con::warnf("@::getAssetByFilename - Attempted to in-place import a file(%s) that had no associated asset", fileName);
+#endif
+
+      AssetImporter* autoAssetImporter;
+      if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
+      {
+         autoAssetImporter = new AssetImporter();
+         autoAssetImporter->registerObject("autoAssetImporter");
+      }
+
+      StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
+
+      if (resultingAssetId != StringTable->EmptyString())
+      {
+         @->setAssetId(resultingAssetId);
+
+         if (!@->isNull())
+            return true;
+      }
+
+      //Didn't work, so have us fall back to a placeholder asset
+      @->setAssetId(StringTable->insert("Core_Rendering:noshape"));
+
+      if (!@->isNull())
+         return true;
+
+      //That didn't work, so fail out
+      return false;
+   }
+   else
+   {
+      //acquire and bind the asset, and return it out
+      @->setAssetId(query.mAssetList[0]);
+      return true;
+   }
+}
+
+StringTableEntry @::getAssetIdByFilename(StringTableEntry fileName)
+{
+   if (fileName == StringTable->EmptyString())
+      return StringTable->EmptyString();
+
+   StringTableEntry @Id = StringTable->EmptyString();
+
+   AssetQuery query;
+   S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
+   if (foundAssetcount == 0)
+   {
+      //Didn't find any assets
+      //If possible, see if we can run an in-place import and the get the asset from that
+#if TORQUE_DEBUG
+      Con::warnf("@::getAssetByFilename - Attempted to in-place import a file(%s) that had no associated asset", fileName);
+#endif
+
+      AssetImporter* autoAssetImporter;
+      if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
+      {
+         autoAssetImporter = new AssetImporter();
+         autoAssetImporter->registerObject("autoAssetImporter");
+      }
+
+      StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
+
+      if (resultingAssetId != StringTable->EmptyString())
+      {
+         @Id = resultingAssetId;
+         return @Id;
+      }
+
+      //Didn't work, so have us fall back to a placeholder asset
+      @Id = StringTable->insert("Core_Rendering:noshape");
+   }
+   else
+   {
+      //acquire and bind the asset, and return it out
+      @Id = query.mAssetList[0];
+   }
+
+   return @Id;
+}
+
+U32 @::getAssetById(StringTableEntry assetId, AssetPtr<@>* @)
+{
+   (*@) = assetId;
+
+   if ((*@))
+      return (*@)->mLoadedState;
+
+   //Didn't work, so have us fall back to a placeholder asset
+   StringTableEntry noShapeId = StringTable->insert("Core_Rendering:noshape");
+   @->setAssetId(noShapeId);
+   (*@)->mLoadedState = AssetErrCode::UsingFallback;
+   if (@->notNull())
+      return AssetErrCode::UsingFallback;
+
+   return AssetErrCode::Failed;
+}
+//------------------------------------------------------------------------------
+
+void @::copyTo(SimObject* object)
+{
+   // Call to parent.
+   Parent::copyTo(object);
+}
+
+void @::onAssetRefresh(void)
+{
+   if (mFileName == StringTable->EmptyString())
+      return;
+
+   // Update.
+   if(!Platform::isFullPath(mFileName))
+      mFilePath = getOwned() ? expandAssetFilePath(mFileName) : mFilePath;
+
+   //Do a loading function here to do the actual load logic
+}
+
+//-----------------------------------------------------------------------------
+// GuiInspectorTypeAssetId
+//-----------------------------------------------------------------------------
+
+#ifdef TORQUE_TOOLS
+IMPLEMENT_CONOBJECT(GuiInspectorType@Ptr);
+
+ConsoleDocClass(GuiInspectorType@Ptr,
+   "@brief Inspector field type for @\n\n"
+   "Editor use only.\n\n"
+   "@internal"
+   );
+
+void GuiInspectorType@Ptr::consoleInit()
+{
+   Parent::consoleInit();
+
+   ConsoleBaseType::getType(Type@Ptr)->setInspectorFieldType("GuiInspectorType@Ptr");
+}
+
+GuiControl* GuiInspectorType@Ptr::constructEditControl()
+{
+   // Create base filename edit controls
+   GuiControl *retCtrl = Parent::constructEditControl();
+   if (retCtrl == NULL)
+      return retCtrl;
+
+   // Change filespec
+   char szBuffer[512];
+   dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"@\", \"AssetBrowser.changeAsset\", %s, %s);", 
+      mInspector->getInspectObject()->getIdString(), mCaption);
+   mBrowseButton->setField("Command", szBuffer);
+
+   const char* id = mInspector->getInspectObject()->getIdString();
+
+   setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString());
+
+   // Create "Open in ShapeEditor" button
+   mShapeEdButton = new GuiBitmapButtonCtrl();
+
+   dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.open@Id(%d.getText());", retCtrl->getId());
+   mShapeEdButton->setField("Command", szBuffer);
+
+   char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
+   mShapeEdButton->setBitmap(bitmapName);
+
+   mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
+   mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
+   mShapeEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
+   mShapeEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the Shape Editor");
+
+   mShapeEdButton->registerObject();
+   addObject(mShapeEdButton);
+
+   return retCtrl;
+}
+
+bool GuiInspectorType@Ptr::updateRects()
+{
+   S32 dividerPos, dividerMargin;
+   mInspector->getDivider(dividerPos, dividerMargin);
+   Point2I fieldExtent = getExtent();
+   Point2I fieldPos = getPosition();
+
+   mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y);
+   mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y);
+
+   bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
+   if (mBrowseButton != NULL)
+   {
+      mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4);
+      resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent);
+   }
+
+   if (mShapeEdButton != NULL)
+   {
+      RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4);
+      resized |= mShapeEdButton->resize(shapeEdRect.point, shapeEdRect.extent);
+   }
+
+   return resized;
+}
+
+IMPLEMENT_CONOBJECT(GuiInspectorType@Id);
+
+ConsoleDocClass(GuiInspectorType@Id,
+   "@brief Inspector field type for @\n\n"
+   "Editor use only.\n\n"
+   "@internal"
+);
+
+void GuiInspectorType@Id::consoleInit()
+{
+   Parent::consoleInit();
+
+   ConsoleBaseType::getType(Type@Id)->setInspectorFieldType("GuiInspectorType@Id");
+}
+
+#endif
+
+DefineEngineMethod(@, getFilePath, const char*, (), ,
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->get@FilePath();
+}

+ 157 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/CppAssetTypeClassFile.h.template

@@ -0,0 +1,157 @@
+#ifndef @_H
+#define @_H
+
+#ifndef _ASSET_BASE_H_
+#include "assets/assetBase.h"
+#endif
+
+#ifndef _ASSET_DEFINITION_H_
+#include "assets/assetDefinition.h"
+#endif
+
+#ifndef _STRINGUNIT_H_
+#include "string/stringUnit.h"
+#endif
+
+#ifndef _ASSET_FIELD_TYPES_H_
+#include "assets/assetFieldTypes.h"
+#endif
+
+#ifndef __RESOURCE_H__
+#include "core/resource.h"
+#endif
+#ifndef _ASSET_PTR_H_
+#include "assets/assetPtr.h"
+#endif 
+
+#ifdef TORQUE_TOOLS
+#include "gui/editor/guiInspectorTypes.h"
+#endif
+
+//-----------------------------------------------------------------------------
+class @ : public AssetBase
+{
+   typedef AssetBase Parent;
+
+protected:
+   StringTableEntry   mFileName;
+   StringTableEntry   mFilePath;
+
+   typedef Signal<void()> @Changed;
+
+   @Changed mChangeSignal;
+
+public:
+   enum @ErrCode
+   {
+      Extended = AssetErrCode::Extended
+   };
+
+   static const String mErrCodeStrings[@ErrCode::Extended - Parent::Extended + 1];
+   static String getAssetErrstrn(U32 errCode)
+   {
+      if (errCode < Parent::Extended) return Parent::getAssetErrstrn(errCode);
+      if (errCode > @ErrCode::Extended) return "undefined error";
+      return mErrCodeStrings[errCode];
+   };
+
+   @();
+   virtual ~@();
+
+   /// Engine.
+   static void initPersistFields();
+   virtual void copyTo(SimObject* object);
+
+   virtual void setDataField(StringTableEntry slotName, const char *array, const char *value);
+
+   virtual void initializeAsset();
+
+   /// Declare Console Object.
+   DECLARE_CONOBJECT(@);
+
+   U32 mLoadedState;
+
+   void _onResourceChanged(const Torque::Path &path);
+
+   @Changed& getChangedSignal() { return mChangeSignal; }
+
+   void                    set@File(const char* pFile);
+   inline StringTableEntry get@File(void) const { return mFileName; };
+
+   inline StringTableEntry get@FilePath(void) const { return mFilePath; };
+
+   static bool getAssetByFilename(StringTableEntry fileName, AssetPtr<@>* @);
+
+   static StringTableEntry getAssetIdByFilename(StringTableEntry fileName);
+   static U32 getAssetById(StringTableEntry assetId, AssetPtr<@>* @);
+
+   static StringTableEntry getNo@Id() { return StringTable->insert("Core_Rendering:noshape"); }
+
+protected:
+   virtual void            onAssetRefresh(void);
+
+   static bool set@File(void* obj, const char* index, const char* data) { static_cast<@*>(obj)->set@File(data); return false; }
+   static const char* get@File(void* obj, const char* data) { return static_cast<@*>(obj)->get@File(); }
+};
+
+#ifdef TORQUE_TOOLS
+DefineConsoleType(Type@Ptr, S32)
+DefineConsoleType(Type@Id, String)
+
+//-----------------------------------------------------------------------------
+// TypeAssetId GuiInspectorField Class
+//-----------------------------------------------------------------------------
+class GuiInspectorType@Ptr : public GuiInspectorTypeFileName
+{
+   typedef GuiInspectorTypeFileName Parent;
+public:
+
+   GuiBitmapButtonCtrl  *mShapeEdButton;
+
+   DECLARE_CONOBJECT(GuiInspectorType@Ptr);
+   static void consoleInit();
+
+   virtual GuiControl* constructEditControl();
+   virtual bool updateRects();
+};
+
+class GuiInspectorType@Id : public GuiInspectorType@Ptr
+{
+   typedef GuiInspectorType@Ptr Parent;
+public:
+
+   DECLARE_CONOBJECT(GuiInspectorType@Id);
+   static void consoleInit();
+};
+#endif
+
+#define assetText(x,suff) std::string(std::string(#x) + std::string(#suff)).c_str()
+
+#define init@(name) m##name##AssetId = StringTable->EmptyString(); m##name##Asset = NULL;
+#define bind@(name) if (m##name##AssetId != StringTable->EmptyString()) m##name##Asset = m##name##AssetId;
+
+#define scriptBind@(name, consoleClass, docs) addProtectedField(assetText(name, Asset), Type@Id, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##Asset, & defaultProtectedGetFn, assetText(name, asset reference.));
+
+#define DECLARE_@(className,name)      protected: \
+                                      StringTableEntry m##name##AssetId;\
+                                      AssetPtr<@>  m##name##Asset;\
+                                      public: \
+                                      const AssetPtr<@> & get##name##Asset() const { return m##name##Asset; }\
+                                      void set##name##Asset(AssetPtr<@>_in) { m##name##Asset = _in; }\
+static bool _set##name##Asset(void* obj, const char* index, const char* data)\
+{\
+   className* shape = static_cast<className*>(obj);\
+   shape->m##name##AssetId = StringTable->insert(data);\
+   if (@::getAssetById(shape->m##name##AssetId, &shape->m##name##Asset))\
+   {\
+      if (shape->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noShape"))\
+         shape->m##name##Filename = StringTable->EmptyString();\
+      \
+      shape->setMaskBits(-1);\
+      return true;\
+   }\
+   return false;\
+}
+
+#endif
+

+ 325 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/CppRenderClassFile.cpp.template

@@ -0,0 +1,325 @@
+#include "@.h"
+#include "platform/platform.h"
+#include "math/mathIO.h"
+#include "scene/sceneRenderState.h"
+#include "console/consoleTypes.h"
+#include "core/stream/bitStream.h"
+#include "materials/materialManager.h"
+#include "materials/baseMatInstance.h"
+#include "renderInstance/renderPassManager.h"
+#include "lighting/lightQuery.h"
+#include "console/engineAPI.h"
+
+
+IMPLEMENT_CO_NETOBJECT_V1(@);
+
+ConsoleDocClass( @, 
+   "@brief An example scene object which renders a mesh.\n\n" );
+
+
+//-----------------------------------------------------------------------------
+// Object setup and teardown
+//-----------------------------------------------------------------------------
+@::@()
+{
+   // Flag this object so that it will always
+   // be sent across the network to clients
+   mNetFlags.set( Ghostable | ScopeAlways );
+
+   // Set it as a "static" object that casts shadows
+   mTypeMask |= StaticObjectType | StaticShapeObjectType;
+
+   // Make sure we the Material instance to NULL
+   // so we don't try to access it incorrectly
+   mMaterialInst = NULL;
+}
+
+@::~@()
+{
+   if ( mMaterialInst )
+      SAFE_DELETE( mMaterialInst );
+}
+
+//-----------------------------------------------------------------------------
+// Object Editing
+//-----------------------------------------------------------------------------
+void @::initPersistFields()
+{
+   addGroup( "Rendering" );
+   addField( "material",      TypeMaterialName, Offset( mMaterialName, @ ),
+      "The name of the material used to render the mesh." );
+   endGroup( "Rendering" );
+
+   // SceneObject already handles exposing the transform
+   Parent::initPersistFields();
+}
+
+void @::inspectPostApply()
+{
+   Parent::inspectPostApply();
+
+   // Flag the network mask to send the updates
+   // to the client object
+   setMaskBits( UpdateMask );
+}
+
+bool @::onAdd()
+{
+   if ( !Parent::onAdd() )
+      return false;
+
+   // Set up a 1x1x1 bounding box
+   mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ),
+                Point3F(  0.5f,  0.5f,  0.5f ) );
+
+   resetWorldBox();
+
+   // Add this object to the scene
+   addToScene();
+
+   // Refresh this object's material (if any)
+   updateMaterial();
+
+   return true;
+}
+
+void @::onRemove()
+{
+   // Remove this object from the scene
+   removeFromScene();
+
+   Parent::onRemove();
+}
+
+void @::setTransform(const MatrixF & mat)
+{
+   // Let SceneObject handle all of the matrix manipulation
+   Parent::setTransform( mat );
+
+   // Dirty our network mask so that the new transform gets
+   // transmitted to the client object
+   setMaskBits( TransformMask );
+}
+
+U32 @::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
+{
+   // Allow the Parent to get a crack at writing its info
+   U32 retMask = Parent::packUpdate( conn, mask, stream );
+
+   // Write our transform information
+   if ( stream->writeFlag( mask & TransformMask ) )
+   {
+      mathWrite(*stream, getTransform());
+      mathWrite(*stream, getScale());
+   }
+
+   // Write out any of the updated editable properties
+   if ( stream->writeFlag( mask & UpdateMask ) )
+      stream->write( mMaterialName );
+
+   return retMask;
+}
+
+void @::unpackUpdate(NetConnection *conn, BitStream *stream)
+{
+   // Let the Parent read any info it sent
+   Parent::unpackUpdate(conn, stream);
+
+   if ( stream->readFlag() )  // TransformMask
+   {
+      mathRead(*stream, &mObjToWorld);
+      mathRead(*stream, &mObjScale);
+
+      setTransform( mObjToWorld );
+   }
+
+   if ( stream->readFlag() )  // UpdateMask
+   {
+      stream->read( &mMaterialName );
+
+      if ( isProperlyAdded() )
+         updateMaterial();
+   }
+}
+
+//-----------------------------------------------------------------------------
+// Object Rendering
+//-----------------------------------------------------------------------------
+void @::createGeometry()
+{
+   static const Point3F cubePoints[8] = 
+   {
+      Point3F( 1, -1, -1), Point3F( 1, -1,  1), Point3F( 1,  1, -1), Point3F( 1,  1,  1),
+      Point3F(-1, -1, -1), Point3F(-1,  1, -1), Point3F(-1, -1,  1), Point3F(-1,  1,  1)
+   };
+
+   static const Point3F cubeNormals[6] = 
+   {
+      Point3F( 1,  0,  0), Point3F(-1,  0,  0), Point3F( 0,  1,  0),
+      Point3F( 0, -1,  0), Point3F( 0,  0,  1), Point3F( 0,  0, -1)
+   };
+
+   static const Point2F cubeTexCoords[4] = 
+   {
+      Point2F( 0,  0), Point2F( 0, -1),
+      Point2F( 1,  0), Point2F( 1, -1)
+   };
+
+   static const U32 cubeFaces[36][3] = 
+   {
+      { 3, 0, 3 }, { 0, 0, 0 }, { 1, 0, 1 },
+      { 2, 0, 2 }, { 0, 0, 0 }, { 3, 0, 3 },
+      { 7, 1, 1 }, { 4, 1, 2 }, { 5, 1, 0 },
+      { 6, 1, 3 }, { 4, 1, 2 }, { 7, 1, 1 },
+      { 3, 2, 1 }, { 5, 2, 2 }, { 2, 2, 0 },
+      { 7, 2, 3 }, { 5, 2, 2 }, { 3, 2, 1 },
+      { 1, 3, 3 }, { 4, 3, 0 }, { 6, 3, 1 },
+      { 0, 3, 2 }, { 4, 3, 0 }, { 1, 3, 3 },
+      { 3, 4, 3 }, { 6, 4, 0 }, { 7, 4, 1 },
+      { 1, 4, 2 }, { 6, 4, 0 }, { 3, 4, 3 },
+      { 2, 5, 1 }, { 4, 5, 2 }, { 0, 5, 0 },
+      { 5, 5, 3 }, { 4, 5, 2 }, { 2, 5, 1 }
+   };
+
+   // Fill the vertex buffer
+   VertexType *pVert = NULL;
+
+   mVertexBuffer.set( GFX, 36, GFXBufferTypeStatic );
+   pVert = mVertexBuffer.lock();
+
+   Point3F halfSize = getObjBox().getExtents() * 0.5f;
+
+   for (U32 i = 0; i < 36; i++)
+   {
+      const U32& vdx = cubeFaces[i][0];
+      const U32& ndx = cubeFaces[i][1];
+      const U32& tdx = cubeFaces[i][2];
+
+      pVert[i].point    = cubePoints[vdx] * halfSize;
+      pVert[i].normal   = cubeNormals[ndx];
+      pVert[i].texCoord = cubeTexCoords[tdx];
+   }
+
+   mVertexBuffer.unlock();
+
+   // Fill the primitive buffer
+   U16 *pIdx = NULL;
+
+   mPrimitiveBuffer.set( GFX, 36, 12, GFXBufferTypeStatic );
+
+   mPrimitiveBuffer.lock(&pIdx);     
+   
+   for (U16 i = 0; i < 36; i++)
+      pIdx[i] = i;
+
+   mPrimitiveBuffer.unlock();
+}
+
+void @::updateMaterial()
+{
+   if ( mMaterialName.isEmpty() )
+      return;
+
+   // If the material name matches then don't bother updating it.
+   if ( mMaterialInst && mMaterialName.equal( mMaterialInst->getMaterial()->getName(), String::NoCase ) )
+      return;
+
+   SAFE_DELETE( mMaterialInst );
+
+   mMaterialInst = MATMGR->createMatInstance( mMaterialName, getGFXVertexFormat< VertexType >() );
+   if ( !mMaterialInst )
+      Con::errorf( "@::updateMaterial - no Material called '%s'", mMaterialName.c_str() );
+}
+
+void @::prepRenderImage( SceneRenderState *state )
+{
+   // Do a little prep work if needed
+   if ( mVertexBuffer.isNull() )
+      createGeometry();
+
+   // If we have no material then skip out.
+   if ( !mMaterialInst || !state)
+      return;
+
+   // If we don't have a material instance after the override then 
+   // we can skip rendering all together.
+   BaseMatInstance *matInst = state->getOverrideMaterial( mMaterialInst );
+   if ( !matInst )
+      return;
+
+   // Get a handy pointer to our RenderPassmanager
+   RenderPassManager *renderPass = state->getRenderPass();
+
+   // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager
+   MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>();
+
+   // Set our RenderInst as a standard mesh render
+   ri->type = RenderPassManager::RIT_Mesh;
+
+   //If our material has transparency set on this will redirect it to proper render bin
+   if ( matInst->getMaterial()->isTranslucent() )
+   {
+      ri->type = RenderPassManager::RIT_Translucent;
+      ri->translucentSort = true;
+   }
+
+   // Calculate our sorting point
+   if ( state )
+   {
+      // Calculate our sort point manually.
+      const Box3F& rBox = getRenderWorldBox();
+      ri->sortDistSq = rBox.getSqDistanceToPoint( state->getCameraPosition() );      
+   } 
+   else 
+      ri->sortDistSq = 0.0f;
+
+   // Set up our transforms
+   MatrixF objectToWorld = getRenderTransform();
+   objectToWorld.scale( getScale() );
+
+   ri->objectToWorld = renderPass->allocUniqueXform( objectToWorld );
+   ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View);
+   ri->projection    = renderPass->allocSharedXform(RenderPassManager::Projection);
+
+	// If our material needs lights then fill the RIs 
+   // light vector with the best lights.
+   if ( matInst->isForwardLit() )
+   {
+      LightQuery query;
+      query.init( getWorldSphere() );
+		query.getLights( ri->lights, 8 );
+   }
+
+   // Make sure we have an up-to-date backbuffer in case
+   // our Material would like to make use of it
+   // NOTICE: SFXBB is removed and refraction is disabled!
+   //ri->backBuffTex = GFX->getSfxBackBuffer();
+
+   // Set our Material
+   ri->matInst = matInst;
+
+   // Set up our vertex buffer and primitive buffer
+   ri->vertBuff = &mVertexBuffer;
+   ri->primBuff = &mPrimitiveBuffer;
+
+   ri->prim = renderPass->allocPrim();
+   ri->prim->type = GFXTriangleList;
+   ri->prim->minIndex = 0;
+   ri->prim->startIndex = 0;
+   ri->prim->numPrimitives = 12;
+   ri->prim->startVertex = 0;
+   ri->prim->numVertices = 36;
+
+   // We sort by the material then vertex buffer
+   ri->defaultKey = matInst->getStateHint();
+   ri->defaultKey2 = (uintptr_t)ri->vertBuff; // Not 64bit safe!
+
+   // Submit our RenderInst to the RenderPassManager
+   state->getRenderPass()->addInst( ri );
+}
+
+DefineEngineMethod( @, postApply, void, (),,
+   "A utility method for forcing a network update.\n")
+{
+	object->inspectPostApply();
+}

+ 102 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/CppRenderClassFile.h.template

@@ -0,0 +1,102 @@
+#ifndef _@_H_
+#define _@_H_
+
+#ifndef _SCENEOBJECT_H_
+#include "scene/sceneObject.h"
+#endif
+#ifndef _GFXVERTEXBUFFER_H_
+#include "gfx/gfxVertexBuffer.h"
+#endif
+#ifndef _GFXPRIMITIVEBUFFER_H_
+#include "gfx/gfxPrimitiveBuffer.h"
+#endif
+
+class BaseMatInstance;
+
+class @ : public SceneObject
+{
+   typedef SceneObject Parent;
+
+   // Networking masks
+   // We need to implement a mask specifically to handle
+   // updating our transform from the server object to its
+   // client-side "ghost". We also need to implement a
+   // maks for handling editor updates to our properties
+   // (like material).
+   enum MaskBits 
+   {
+      TransformMask = Parent::NextFreeMask << 0,
+      UpdateMask    = Parent::NextFreeMask << 1,
+      NextFreeMask  = Parent::NextFreeMask << 2
+   };
+
+   //--------------------------------------------------------------------------
+   // Rendering variables
+   //--------------------------------------------------------------------------
+   // The name of the Material we will use for rendering
+   String            mMaterialName;
+   // The actual Material instance
+   BaseMatInstance*  mMaterialInst;
+
+   // Define our vertex format here so we don't have to
+   // change it in multiple spots later
+   typedef GFXVertexPNT VertexType;
+
+   // The GFX vertex and primitive buffers
+   GFXVertexBufferHandle< VertexType > mVertexBuffer;
+   GFXPrimitiveBufferHandle            mPrimitiveBuffer;
+
+public:
+   @();
+   virtual ~@();
+
+   // Handle when we are added to the scene and removed from the scene
+   bool onAdd();
+   void onRemove();
+
+   // Declare this object as a ConsoleObject so that we can
+   // instantiate it into the world and network it
+   DECLARE_CONOBJECT(@);
+
+   //--------------------------------------------------------------------------
+   // Object Editing
+   // Since there is always a server and a client object in Torque and we
+   // actually edit the server object we need to implement some basic
+   // networking functions
+   //--------------------------------------------------------------------------
+   // Set up any fields that we want to be editable (like position)
+   static void initPersistFields();
+
+   // Allows the object to update its editable settings
+   // from the server object to the client
+   virtual void inspectPostApply();
+
+   // Override this so that we can dirty the network flag when it is called
+   void setTransform( const MatrixF &mat );
+
+   // This function handles sending the relevant data from the server
+   // object to the client object
+   U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
+   // This function handles receiving relevant data from the server
+   // object and applying it to the client object
+   void unpackUpdate( NetConnection *conn, BitStream *stream );
+
+   //--------------------------------------------------------------------------
+   // Object Rendering
+   // Torque utilizes a "batch" rendering system. This means that it builds a
+   // list of objects that need to render (via RenderInst's) and then renders
+   // them all in one batch. This allows it to optimized on things like
+   // minimizing texture, state, and shader switching by grouping objects that
+   // use the same Materials.
+   //--------------------------------------------------------------------------
+   // Create the geometry for rendering
+   void createGeometry();
+
+   // Get the Material instance
+   void updateMaterial();
+
+   // This is the function that allows this object to submit itself for rendering
+   void prepRenderImage( SceneRenderState *state );
+};
+
+#endif // _@_H_

+ 105 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/CppSceneObjectClassFile.cpp.template

@@ -0,0 +1,105 @@
+#include "@.h"
+#include "math/mathIO.h"
+#include "console/consoleTypes.h"
+#include "core/stream/bitStream.h"
+
+
+IMPLEMENT_CO_NETOBJECT_V1(@);
+
+@::@()
+{
+   // Flag this object so that it will always
+   // be sent across the network to clients
+   mNetFlags.set( Ghostable | ScopeAlways );
+
+   // Set it as a "static" object that casts shadows
+   mTypeMask |= StaticObjectType | StaticShapeObjectType;
+}
+
+@::~@()
+{
+}
+
+bool @::onAdd()
+{
+   if (!Parent::onAdd())
+      return false;
+
+   // Set up a 1x1x1 bounding box
+   mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ),
+                Point3F(  0.5f,  0.5f,  0.5f ) );
+
+   resetWorldBox();
+
+   // Add this object to the scene
+   addToScene();
+
+   return true;
+}
+
+void @::onRemove()
+{
+   // Remove this object from the scene
+   removeFromScene();
+
+   Parent::onRemove();
+}
+
+void @::initPersistFields()
+{
+   Parent::initPersistFields();
+}
+
+void @::inspectPostApply()
+{
+   Parent::inspectPostApply();
+
+   // Flag the network mask to send the updates
+   // to the client object
+   setMaskBits( TransformMask );
+}
+
+void @::setTransform(const MatrixF & mat)
+{
+   // Let SceneObject handle all of the matrix manipulation
+   Parent::setTransform( mat );
+
+   // Dirty our network mask so that the new transform gets
+   // transmitted to the client object
+   setMaskBits( TransformMask );
+}
+
+U32 @::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
+{
+   // Allow the Parent to get a crack at writing its info
+   U32 retMask = Parent::packUpdate( conn, mask, stream );
+
+   // Write our transform information
+   if ( stream->writeFlag( mask & TransformMask ) )
+   {
+      mathWrite(*stream, getTransform());
+      mathWrite(*stream, getScale());
+   }
+
+   return retMask;
+}
+
+void @::unpackUpdate(NetConnection *conn, BitStream *stream)
+{
+   // Let the Parent read any info it sent
+   Parent::unpackUpdate(conn, stream);
+
+   if ( stream->readFlag() )  // TransformMask
+   {
+      mathRead(*stream, &mObjToWorld);
+      mathRead(*stream, &mObjScale);
+
+      setTransform( mObjToWorld );
+   }
+}
+
+DefineEngineMethod( @, postApply, void, (),,
+   "A utility method for forcing a network update.\n")
+{
+	object->inspectPostApply();
+}

+ 53 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/CppSceneObjectClassFile.h.template

@@ -0,0 +1,53 @@
+#pragma once
+
+#ifndef _SCENEOBJECT_H_
+#include "scene/sceneObject.h"
+#endif
+
+class @ : public SceneObject
+{
+   typedef SceneObject Parent;
+
+private:
+   enum MaskBits 
+   {
+      TransformMask = Parent::NextFreeMask << 0,
+      NextFreeMask  = Parent::NextFreeMask << 1
+   };
+
+protected:
+
+public:
+   @();
+   virtual ~@();
+
+   // Declare this object as a ConsoleObject so that we can
+   // instantiate it into the world and network it
+   DECLARE_CONOBJECT(@);
+
+   // Handle when we are added to the scene and removed from the scene
+   bool onAdd();
+   void onRemove();
+
+   // Set up any fields that we want to be editable (like position)
+   static void initPersistFields();
+
+   // Allows the object to update its editable settings
+   // from the server object to the client
+   virtual void inspectPostApply();
+
+   // Override this so that we can dirty the network flag when it is called
+   void setTransform( const MatrixF &mat );
+
+   // This function handles sending the relevant data from the server
+   // object to the client object
+   U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
+
+   // This function handles receiving relevant data from the server
+   // object and applying it to the client object
+   void unpackUpdate( NetConnection *conn, BitStream *stream );
+
+   virtual void interpolateTick( F32 delta );
+   virtual void processTick();
+   virtual void advanceTime( F32 timeDelta );
+};

+ 45 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/CppScriptClassFile.cpp.template

@@ -0,0 +1,45 @@
+#include "@.h"
+
+
+IMPLEMENT_CONOBJECT(@);
+
+@::@()
+{
+}
+
+@::~@()
+{
+}
+
+void @::initPersistFields()
+{
+   Parent::initPersistFields();
+}
+
+bool @::onAdd()
+{
+   if (!Parent::onAdd())
+      return false;
+
+   return true;
+}
+
+void @::onRemove()
+{
+   Parent::onRemove();
+}
+
+void @::interpolateTick( F32 delta )
+{
+   Parent::interpolateTick(delta);
+}
+
+void @::processTick()
+{
+   Parent::processTick();
+}
+
+void @::advanceTime( F32 timeDelta )
+{
+	Parent::advanceTime(timeDelta);
+}

+ 29 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/CppScriptClassFile.h.template

@@ -0,0 +1,29 @@
+#pragma once
+
+#include "console/engineAPI.h"
+#include "console/scriptObjects.h"
+
+class @ : public ScriptTickObject
+{
+   typedef ScriptTickObject Parent;
+
+private:
+
+protected:
+
+public:
+   @();
+   ~@();
+
+   // Declare this object as a ConsoleObject so that we can
+   // instantiate it
+   DECLARE_CONOBJECT(@);
+
+   static void initPersistFields();
+   bool onAdd();
+   void onRemove();
+
+   virtual void interpolateTick( F32 delta );
+   virtual void processTick();
+   virtual void advanceTime( F32 timeDelta );
+};