2
0
Эх сурвалжийг харах

Merge branch 'Preview4_0' of https://github.com/TorqueGameEngines/Torque3D into Preview4_0_MenuUIRework

Areloch 5 жил өмнө
parent
commit
69089e1ee2
100 өөрчлөгдсөн 3454 нэмэгдсэн , 112 устгасан
  1. 45 1
      Engine/source/T3D/assets/ImageAsset.cpp
  2. 6 0
      Engine/source/T3D/assets/ImageAsset.h
  3. 24 19
      Engine/source/T3D/assets/ShapeAsset.cpp
  4. 2093 0
      Engine/source/T3D/assets/assetImporter.cpp
  5. 777 0
      Engine/source/T3D/assets/assetImporter.h
  6. 140 0
      Engine/source/T3D/assets/assetImporter_ScriptBinding.h
  7. 3 0
      Engine/source/T3D/cameraSpline.cpp
  8. 2 2
      Engine/source/T3D/convexShape.cpp
  9. 2 2
      Engine/source/T3D/convexShape.h
  10. 2 0
      Engine/source/T3D/debris.cpp
  11. 17 0
      Engine/source/T3D/decal/decalInstance.cpp
  12. 1 1
      Engine/source/T3D/decal/decalInstance.h
  13. 5 1
      Engine/source/T3D/fx/explosion.cpp
  14. 11 1
      Engine/source/T3D/fx/fxFoliageReplicator.cpp
  15. 12 1
      Engine/source/T3D/fx/lightning.cpp
  16. 2 1
      Engine/source/T3D/fx/particleEmitter.cpp
  17. 1 0
      Engine/source/T3D/fx/ribbon.cpp
  18. 0 3
      Engine/source/T3D/fx/ribbonNode.h
  19. 3 1
      Engine/source/T3D/fx/splash.cpp
  20. 1 0
      Engine/source/T3D/gameBase/gameBase.cpp
  21. 1 0
      Engine/source/T3D/gameBase/moveList.cpp
  22. 2 0
      Engine/source/T3D/guiMaterialPreview.cpp
  23. 14 0
      Engine/source/T3D/lighting/IBLUtilities.cpp
  24. 1 0
      Engine/source/T3D/physics/physicsForce.cpp
  25. 8 0
      Engine/source/T3D/player.cpp
  26. 1 0
      Engine/source/T3D/rigidShape.cpp
  27. 1 1
      Engine/source/T3D/shapeBase.cpp
  28. 1 1
      Engine/source/T3D/shapeBase.h
  29. 4 0
      Engine/source/T3D/shapeImage.cpp
  30. 10 3
      Engine/source/T3D/tsStatic.cpp
  31. 1 0
      Engine/source/T3D/turret/aiTurretShape.cpp
  32. 9 3
      Engine/source/T3D/turret/turretShape.cpp
  33. 5 0
      Engine/source/T3D/vehicles/flyingVehicle.cpp
  34. 0 1
      Engine/source/T3D/vehicles/flyingVehicle.h
  35. 12 6
      Engine/source/T3D/vehicles/hoverVehicle.cpp
  36. 1 1
      Engine/source/T3D/vehicles/wheeledVehicle.cpp
  37. 4 2
      Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.cpp
  38. 3 2
      Engine/source/Verve/VActor/VActorPhysicsController.cpp
  39. 5 3
      Engine/source/Verve/VPath/VPathEditor.h
  40. 0 2
      Engine/source/afx/afxCamera.h
  41. 6 0
      Engine/source/afx/afxConstraint.cpp
  42. 1 0
      Engine/source/afx/afxEffectVector.cpp
  43. 0 2
      Engine/source/afx/afxEffectWrapper.h
  44. 3 2
      Engine/source/afx/afxMagicMissile.cpp
  45. 8 0
      Engine/source/afx/afxZodiacGroundPlaneRenderer_T3D.cpp
  46. 8 0
      Engine/source/afx/afxZodiacMeshRoadRenderer_T3D.cpp
  47. 8 0
      Engine/source/afx/afxZodiacPolysoupRenderer_T3D.cpp
  48. 8 0
      Engine/source/afx/afxZodiacTerrainRenderer_T3D.cpp
  49. 6 1
      Engine/source/afx/ce/afxModel.cpp
  50. 3 1
      Engine/source/afx/ce/afxMooring.cpp
  51. 5 0
      Engine/source/afx/ce/afxParticleEmitter.cpp
  52. 2 1
      Engine/source/afx/ce/afxStaticShape.cpp
  53. 1 0
      Engine/source/afx/ce/afxZodiac.cpp
  54. 2 2
      Engine/source/afx/ce/afxZodiacPlane.cpp
  55. 1 0
      Engine/source/afx/ea/afxEA_PhraseEffect.cpp
  56. 7 6
      Engine/source/afx/forces/afxF_Drag.cpp
  57. 5 4
      Engine/source/afx/forces/afxF_Gravity.cpp
  58. 3 1
      Engine/source/afx/util/afxAnimCurve.cpp
  59. 2 2
      Engine/source/afx/util/afxCurve3D.cpp
  60. 1 1
      Engine/source/afx/util/afxPath3D.cpp
  61. 15 5
      Engine/source/app/net/httpObject.cpp
  62. 1 0
      Engine/source/app/net/serverQuery.h
  63. 1 1
      Engine/source/collision/boxConvex.cpp
  64. 3 1
      Engine/source/collision/clippedPolyList.h
  65. 5 1
      Engine/source/collision/collision.h
  66. 3 0
      Engine/source/collision/concretePolyList.h
  67. 11 6
      Engine/source/collision/convex.cpp
  68. 2 2
      Engine/source/collision/convex.h
  69. 7 0
      Engine/source/collision/depthSortList.cpp
  70. 1 0
      Engine/source/collision/extrudedPolyList.cpp
  71. 5 2
      Engine/source/collision/extrudedPolyList.h
  72. 13 0
      Engine/source/collision/gjk.cpp
  73. 2 0
      Engine/source/collision/optimizedPolyList.h
  74. 1 0
      Engine/source/collision/planeExtractor.cpp
  75. 1 0
      Engine/source/collision/polytope.h
  76. 1 0
      Engine/source/console/astNodes.cpp
  77. 3 0
      Engine/source/console/codeBlock.cpp
  78. 3 0
      Engine/source/console/codeInterpreter.cpp
  79. 1 1
      Engine/source/console/compiler.h
  80. 12 1
      Engine/source/console/consoleInternal.cpp
  81. 1 0
      Engine/source/console/consoleInternal.h
  82. 16 1
      Engine/source/console/consoleObject.h
  83. 1 1
      Engine/source/console/engineAPI.h
  84. 2 1
      Engine/source/console/engineExports.h
  85. 1 1
      Engine/source/console/engineObject.cpp
  86. 1 0
      Engine/source/console/engineTypeInfo.cpp
  87. 1 0
      Engine/source/console/simDatablock.cpp
  88. 2 0
      Engine/source/console/simDictionary.cpp
  89. 1 1
      Engine/source/console/simEvents.h
  90. 2 2
      Engine/source/console/simFieldDictionary.h
  91. 4 0
      Engine/source/console/simObject.cpp
  92. 1 0
      Engine/source/console/simObject.h
  93. 6 0
      Engine/source/console/stringStack.cpp
  94. 3 0
      Engine/source/console/telnetConsole.cpp
  95. 1 0
      Engine/source/console/telnetConsole.h
  96. 3 0
      Engine/source/console/telnetDebugger.cpp
  97. 2 1
      Engine/source/console/typeValidators.h
  98. 2 1
      Engine/source/core/color.h
  99. 1 0
      Engine/source/core/frameAllocator.h
  100. 2 2
      Engine/source/core/ogg/oggTheoraDecoder.h

+ 45 - 1
Engine/source/T3D/assets/ImageAsset.cpp

@@ -103,7 +103,7 @@ EndImplementEnumType;
 
 
 //-----------------------------------------------------------------------------
-ImageAsset::ImageAsset() : AssetBase(), mImage(nullptr), mUseMips(true), mIsHDRImage(false), mIsValidImage(false)
+ImageAsset::ImageAsset() : AssetBase(), mImage(nullptr), mUseMips(true), mIsHDRImage(false), mIsValidImage(false), mImageType(Albedo)
 {
    mImageFileName = StringTable->EmptyString();
 }
@@ -239,6 +239,50 @@ const char* ImageAsset::getImageInfo()
    return "";
 }
 
+const char* ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes type)
+{
+   // must match ImageTypes order
+   static const char* _names[] = {
+      "Albedo"
+      "Normal"
+      "Composite"
+      "GUI"
+      "Roughness"
+      "AO"
+      "Metalness"
+      "Glow"
+      "Particle"
+      "Decal"
+      "Cubemap"
+   };
+
+   if (type < 0 || type >= ImageTypeCount)
+   {
+      Con::errorf("ImageAsset::getAdapterNameFromType - Invalid ImageType, defaulting to Albedo");
+      return _names[Albedo];
+   }
+
+   return _names[type];
+}
+
+ImageAsset::ImageTypes ImageAsset::getImageTypeFromName(const char* name)
+{
+   S32 ret = -1;
+   for (S32 i = 0; i < ImageTypeCount; i++)
+   {
+      if (!dStricmp(getImageTypeNameFromType((ImageTypes)i), name))
+         ret = i;
+   }
+
+   if (ret == -1)
+   {
+      Con::errorf("ImageAsset::getImageTypeFromName - Invalid ImageType name, defaulting to Albedo");
+      ret = Albedo;
+   }
+
+   return (ImageTypes)ret;
+}
+
 DefineEngineMethod(ImageAsset, getImageFilename, const char*, (), ,
    "Creates an instance of the given GameObject given the asset definition.\n"
    "@return The GameObject entity created from the asset.")

+ 6 - 0
Engine/source/T3D/assets/ImageAsset.h

@@ -65,6 +65,7 @@ public:
       Particle = 8,
       Decal = 9,
       Cubemap = 10,
+      ImageTypeCount = 11
    };
 
 protected:
@@ -100,6 +101,11 @@ public:
 
    const char* getImageInfo();
 
+   static const char* getImageTypeNameFromType(ImageTypes type);
+   static ImageTypes getImageTypeFromName(const char* name);
+
+   void setImageType(ImageTypes type) { mImageType = type; }
+
 protected:
    virtual void            initializeAsset(void);
    virtual void            onAssetRefresh(void);

+ 24 - 19
Engine/source/T3D/assets/ShapeAsset.cpp

@@ -44,6 +44,7 @@
 
 // Debug Profiling.
 #include "platform/profiler.h"
+#include "T3D/assets/assetImporter.h"
 
 //-----------------------------------------------------------------------------
 
@@ -329,19 +330,21 @@ bool ShapeAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr<ShapeAss
       Con::warnf("ShapeAsset::getAssetByFilename - Attempted to in-place import a shapefile(%s) that had no associated asset", fileName);
 #endif
 
-      ConsoleValueRef result = Con::executef("importLooseFile", fileName, true);
-
-      if (result.getBoolValue())
+      AssetImporter* autoAssetImporter;
+      if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
       {
-         StringTableEntry resultingAssetId = StringTable->insert(Con::getVariable("$importedLooseFileAsset"));
+         autoAssetImporter = new AssetImporter();
+         autoAssetImporter->registerObject("autoAssetImporter");
+      }
 
-         if (resultingAssetId != StringTable->EmptyString())
-         {
-            shapeAsset->setAssetId(resultingAssetId);
+      StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
 
-            if (!shapeAsset->isNull())
-               return true;
-         }
+      if (resultingAssetId != StringTable->EmptyString())
+      {
+         shapeAsset->setAssetId(resultingAssetId);
+
+         if (!shapeAsset->isNull())
+            return true;
       }
 
       //Didn't work, so have us fall back to a placeholder asset
@@ -375,17 +378,19 @@ StringTableEntry ShapeAsset::getAssetIdByFilename(StringTableEntry fileName)
       Con::warnf("ShapeAsset::getAssetByFilename - Attempted to in-place import a shapefile(%s) that had no associated asset", fileName);
 #endif
 
-      ConsoleValueRef result = Con::executef("importLooseFile", fileName, true);
-
-      if (result.getBoolValue())
+      AssetImporter* autoAssetImporter;
+      if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
       {
-         StringTableEntry resultingAssetId = StringTable->insert(Con::getVariable("$importedLooseFileAsset"));
+         autoAssetImporter = new AssetImporter();
+         autoAssetImporter->registerObject("autoAssetImporter");
+      }
 
-         if (resultingAssetId != StringTable->EmptyString())
-         {
-            shapeAssetId = resultingAssetId;
-            return shapeAssetId;
-         }
+      StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
+
+      if (resultingAssetId != StringTable->EmptyString())
+      {
+         shapeAssetId = resultingAssetId;
+         return shapeAssetId;
       }
 
       //Didn't work, so have us fall back to a placeholder asset

+ 2093 - 0
Engine/source/T3D/assets/assetImporter.cpp

@@ -0,0 +1,2093 @@
+#include "assetImporter.h"
+#include "assetImporter_ScriptBinding.h"
+#include "core/strings/findMatch.h"
+#include "ImageAsset.h"
+#include "ShapeAsset.h"
+#include "SoundAsset.h"
+#include "MaterialAsset.h"
+#include "ShapeAnimationAsset.h"
+
+#include "ts/collada/colladaUtils.h"
+#include "ts/collada/colladaAppNode.h"
+#include "ts/collada/colladaShapeLoader.h"
+
+#include "ts/assimp/assimpShapeLoader.h"
+#include "ts/tsShapeConstruct.h"
+
+
+ConsoleDocClass(AssetImportConfig,
+   "@brief Defines properties for an AssetImprotConfig object.\n"
+   "@AssetImportConfig is a SimObject derived object intended to act as a container for all the necessary configuration data when running the Asset Importer.\n"
+   "@It dictates if and how any given asset type will be processed when running an import action. This is because the Asset Importer utilizes a lot of informed logic\n"
+   "@to try and automate as much of the import process as possible. In theory, you would run the import on a given file, and based on your config the importer will do\n"
+   "@everything from importing the designated file, as well as finding and importing any associated files such as images or materials, and prepping the objects at time\n"
+   "@of import to avoid as much manual post-processing as possible.\n\n"
+   "@ingroup Assets\n"
+);
+
+IMPLEMENT_CONOBJECT(AssetImportConfig);
+
+AssetImportConfig::AssetImportConfig() :
+   DuplicatAutoResolution("AutoRename"),
+   WarningsAsErrors(false),
+   PreventImportWithErrors(true),
+   AutomaticallyPromptMissingFiles(false),
+   ImportMesh(true),
+   DoUpAxisOverride(false),
+   UpAxisOverride("Z_AXIS"),
+   DoScaleOverride(false),
+   ScaleOverride(false),
+   IgnoreNodeScale(false),
+   AdjustCenter(false),
+   AdjustFloor(false),
+   CollapseSubmeshes(false),
+   LODType("TrailingNumber"),
+   ImportedNodes(""),
+   IgnoreNodes(""),
+   ImportMeshes(""),
+   IgnoreMeshes(""),
+   convertLeftHanded(false),
+   calcTangentSpace(false),
+   removeRedundantMats(false),
+   genUVCoords(false),
+   TransformUVs(false),
+   flipUVCoords(false),
+   findInstances(false),
+   limitBoneWeights(false),
+   JoinIdenticalVerts(false),
+   reverseWindingOrder(false),
+   invertNormals(false),
+   ImportMaterials(true),
+   CreatePBRConfig(true),
+   UseDiffuseSuffixOnOriginImage(false),
+   UseExistingMaterials(false),
+   IgnoreMaterials(""),
+   PopulateMaterialMaps(false),
+   ImportAnimations(true),
+   SeparateAnimations(false),
+   SeparateAnimationPrefix(""),
+   animTiming("FrameCount"),
+   animFPS(false),
+   GenerateCollisions(false),
+   GenCollisionType(""),
+   CollisionMeshPrefix(""),
+   GenerateLOSCollisions(false),
+   GenLOSCollisionType(""),
+   LOSCollisionMeshPrefix(""),
+   importImages(true),
+   ImageType("GUI"),
+   DiffuseTypeSuffixes("_ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL,_A,_C,-ALBEDO,-DIFFUSE,-ALB,-DIF,-COLOR,-COL,-A,-C"),
+   NormalTypeSuffixes("_NORMAL,_NORM,_N,-NORMAL,-NORM,-N"),
+   MetalnessTypeSuffixes("_METAL,_MET,_METALNESS,_METALLIC,_M,-METAL, -MET, -METALNESS, -METALLIC, -M"),
+   RoughnessTypeSuffixes("_ROUGH,_ROUGHNESS,_R,-ROUGH,-ROUGHNESS,-R"),
+   SmoothnessTypeSuffixes("_SMOOTH,_SMOOTHNESS,_S,-SMOOTH,-SMOOTHNESS,-S"),
+   AOTypeSuffixes("_AO,_AMBIENT,_AMBIENTOCCLUSION,-AO,-AMBIENT,-AMBIENTOCCLUSION"),
+   PBRTypeSuffixes("_COMP,_COMPOSITE,_PBR,-COMP,-COMPOSITE,-PBR"),
+   TextureFilteringMode("Bilinear"),
+   UseMips(true),
+   IsHDR(false),
+   Scaling(false),
+   ImagesCompressed(false),
+   GenerateMaterialOnImport(true),
+   importSounds(true),
+   VolumeAdjust(false),
+   PitchAdjust(false),
+   SoundsCompressed(false)
+{
+}
+
+AssetImportConfig::~AssetImportConfig()
+{
+
+}
+
+/// Engine.
+void AssetImportConfig::initPersistFields()
+{
+   Parent::initPersistFields();
+
+   addGroup("General");
+      addField("DuplicatAutoResolution", TypeString, Offset(DuplicatAutoResolution, AssetImportConfig), "Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename");
+      addField("WarningsAsErrors", TypeBool, Offset(WarningsAsErrors, AssetImportConfig), "Indicates if warnings should be treated as errors");
+      addField("PreventImportWithErrors", TypeBool, Offset(PreventImportWithErrors, AssetImportConfig), "Indicates if importing should be prevented from completing if any errors are detected at all");
+      addField("AutomaticallyPromptMissingFiles", TypeBool, Offset(AutomaticallyPromptMissingFiles, AssetImportConfig), "Should the importer automatically prompt to find missing files if they are not detected automatically by the importer");
+   endGroup("General");
+
+   addGroup("Meshes");
+      addField("ImportMesh", TypeBool, Offset(ImportMesh, AssetImportConfig), "Indicates if this config supports importing meshes");
+      addField("DoUpAxisOverride", TypeBool, Offset(DoUpAxisOverride, AssetImportConfig), "Indicates if the up axis in the model file should be overridden ");
+      addField("UpAxisOverride", TypeString, Offset(UpAxisOverride, AssetImportConfig), "If overriding, what axis should be used as up. Options are X_AXIS, Y_AXIS, Z_AXIS");
+      addField("DoScaleOverride", TypeBool, Offset(DoScaleOverride, AssetImportConfig), "Indicates if the scale in the model file should be overridden");
+      addField("ScaleOverride", TypeF32, Offset(ScaleOverride, AssetImportConfig), "If overriding, what scale should be used");
+      addField("IgnoreNodeScale", TypeBool, Offset(IgnoreNodeScale, AssetImportConfig), "Indicates if scale of nodes should be ignored");
+      addField("AdjustCenter", TypeBool, Offset(AdjustCenter, AssetImportConfig), "Indicates if the center of the model file should be automatically recentered");
+      addField("AdjustFloor", TypeBool, Offset(AdjustFloor, AssetImportConfig), "Indicates if the floor height of the model file should be automatically zero'd");
+      addField("CollapseSubmeshes", TypeBool, Offset(CollapseSubmeshes, AssetImportConfig), "Indicates if submeshes should be collapsed down into a single main mesh");
+      addField("LODType", TypeString, Offset(LODType, AssetImportConfig), "Indicates what LOD mode the model file should utilize to process out LODs. Options are TrailingNumber, DetectDTS, SingleSize");
+      addField("ImportedNodes", TypeString, Offset(ImportedNodes, AssetImportConfig), " A list of what nodes should be guaranteed to be imported if found in the model file. Separated by either , or ;");
+      addField("IgnoreNodes", TypeString, Offset(IgnoreNodes, AssetImportConfig), "A list of what nodes should be guaranteed to not be imported if found in the model file. Separated by either , or ;");
+      addField("ImportMeshes", TypeString, Offset(ImportMeshes, AssetImportConfig), "A list of what mesh objects should be guaranteed to be imported if found in the model file. Separated by either , or ;");
+      addField("IgnoreMeshes", TypeString, Offset(IgnoreMeshes, AssetImportConfig), "A list of what mesh objects should be guaranteed to not be imported if found in the model file. Separated by either , or ;");
+      addField("convertLeftHanded", TypeBool, Offset(convertLeftHanded, AssetImportConfig), "Flag to indicate the shape loader should convert to a left-handed coordinate system");
+      addField("calcTangentSpace", TypeBool, Offset(calcTangentSpace, AssetImportConfig), "Should the shape loader calculate tangent space values");
+      addField("removeRedundantMats", TypeBool, Offset(removeRedundantMats, AssetImportConfig), "Should the shape loader automatically prune redundant/duplicate materials");
+      addField("genUVCoords", TypeBool, Offset(genUVCoords, AssetImportConfig), "Should the shape loader auto-generate UV Coordinates for the mesh.");
+      addField("TransformUVs", TypeBool, Offset(TransformUVs, AssetImportConfig), "Should the UV coordinates be transformed");
+      addField("flipUVCoords", TypeBool, Offset(flipUVCoords, AssetImportConfig), "Should the UV coordinates be flipped");
+      addField("findInstances", TypeBool, Offset(findInstances, AssetImportConfig), "Should the shape loader automatically look for instanced submeshes in the model file");
+      addField("limitBoneWeights", TypeBool, Offset(limitBoneWeights, AssetImportConfig), "Should the shape loader limit the bone weights");
+      addField("JoinIdenticalVerts", TypeBool, Offset(JoinIdenticalVerts, AssetImportConfig), "Should the shape loader automatically merge identical/duplicate verts");
+      addField("reverseWindingOrder", TypeBool, Offset(reverseWindingOrder, AssetImportConfig), "Should the shape loader reverse the winding order of the mesh's face indicies");
+      addField("invertNormals", TypeBool, Offset(invertNormals, AssetImportConfig), "Should the normals on the model be inverted");
+   endGroup("Meshes");
+
+   addGroup("Materials");
+      addField("DuplicatAutoResolution", TypeString, Offset(DuplicatAutoResolution, AssetImportConfig), "Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename");
+      addField("ImportMaterials", TypeBool, Offset(ImportMaterials, AssetImportConfig), "Does this config allow for importing of materials");
+      addField("CreatePBRConfig", TypeBool, Offset(PreventImportWithErrors, AssetImportConfig), "When importing a material, should it automatically attempt to merge Roughness, AO and Metalness maps into a single, composited PBR Configuration map");
+      addField("UseDiffuseSuffixOnOriginImage", TypeBool, Offset(UseDiffuseSuffixOnOriginImage, AssetImportConfig), "When generating a material off of an importing image, should the importer force appending a diffusemap suffix onto the end to avoid potential naming confusion.\n e.g. MyCoolStuff.png is imported, generating MyCoolStuff material asset and MyCoolStuff_Diffuse image asset");
+      addField("UseExistingMaterials", TypeBool, Offset(UseExistingMaterials, AssetImportConfig), "Should the importer try and use existing material assets in the game directory if at all possible. (Not currently utilized)");
+      addField("IgnoreMaterials", TypeString, Offset(IgnoreMaterials, AssetImportConfig), "A list of material names that should not be imported. Separated by either , or ;");
+      addField("PopulateMaterialMaps", TypeBool, Offset(PopulateMaterialMaps, AssetImportConfig), "When processing a material asset, should the importer attempt to populate the various material maps on it by looking up common naming conventions for potentially relevent image files.\n e.g. If MyCoolStuff_Diffuse.png is imported, generating MyCoolStuff material, it would also find MyCoolStuff_Normal and MyCoolStuff_PBR images and map them to the normal and PBRConfig maps respectively automatically");
+   endGroup("Materials");
+
+   addGroup("Meshes");
+      addField("ImportAnimations", TypeBool, Offset(ImportAnimations, AssetImportConfig), "Does this config allow for importing Shape Animations");
+      addField("SeparateAnimations", TypeBool, Offset(SeparateAnimations, AssetImportConfig), "When importing a shape file, should the animations within be separated out into unique files");
+      addField("SeparateAnimationPrefix", TypeString, Offset(SeparateAnimationPrefix, AssetImportConfig), "If separating animations out from a source file, what prefix should be added to the names for grouping association");
+      addField("animTiming", TypeString, Offset(animTiming, AssetImportConfig), "Defines the animation timing for the given animation sequence. Options are FrameTime, Seconds, Milliseconds");
+      addField("animFPS", TypeBool, Offset(animFPS, AssetImportConfig), "The FPS of the animation sequence");
+   endGroup("General");
+
+   addGroup("Collision");
+      addField("GenerateCollisions", TypeBool, Offset(GenerateCollisions, AssetImportConfig), "Does this configuration generate collision geometry when importing. (Not currently enabled)");
+      addField("GenCollisionType", TypeString, Offset(GenCollisionType, AssetImportConfig), "What sort of collision geometry is generated. (Not currently enabled)");
+      addField("CollisionMeshPrefix", TypeString, Offset(CollisionMeshPrefix, AssetImportConfig), "What prefix is added to the collision geometry generated. (Not currently enabled)");
+      addField("GenerateLOSCollisions", TypeBool, Offset(GenerateLOSCollisions, AssetImportConfig), "Does this configuration generate Line of Sight collision geometry. (Not currently enabled)");
+      addField("GenLOSCollisionType", TypeString, Offset(GenLOSCollisionType, AssetImportConfig), "What sort of Line of Sight collision geometry is generated. (Not currently enabled)");
+      addField("LOSCollisionMeshPrefix", TypeString, Offset(LOSCollisionMeshPrefix, AssetImportConfig), "What prefix is added to the Line of Sight collision geometry generated. (Not currently enabled)");
+   endGroup("Collision");
+
+   addGroup("Images");
+      addField("importImages", TypeBool, Offset(importImages, AssetImportConfig), "Does this configuration support importing images.");
+      addField("ImageType", TypeString, Offset(ImageType, AssetImportConfig), "What is the default ImageType images are imported as. Options are: N/A, Diffuse, Normal, Metalness, Roughness, AO, PBRConfig, GUI, Cubemap");
+      addField("DiffuseTypeSuffixes", TypeString, Offset(DiffuseTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a diffuse map. \n e.g. _Albedo or _Color");
+      addField("NormalTypeSuffixes", TypeString, Offset(NormalTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a normal map. \n e.g. _Normal or _Norm");
+      addField("MetalnessTypeSuffixes", TypeString, Offset(MetalnessTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a metalness map. \n e.g. _Metalness or _Metal");
+      addField("RoughnessTypeSuffixes", TypeString, Offset(RoughnessTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a roughness map.\n e.g. _roughness or _rough");
+      addField("SmoothnessTypeSuffixes", TypeString, Offset(SmoothnessTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a smoothness map. \n e.g. _smoothness or _smooth");
+      addField("AOTypeSuffixes", TypeString, Offset(AOTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a ambient occlusion map. \n e.g. _ambient or _ao");
+      addField("PBRTypeSuffixes", TypeString, Offset(PBRTypeSuffixes, AssetImportConfig), "What type of suffixes are scanned to detect if an importing image is a PBRConfig map.\n e.g. _Composite or _PBR");
+      addField("TextureFilteringMode", TypeString, Offset(TextureFilteringMode, AssetImportConfig), "Indicates what filter mode images imported with this configuration utilizes. Options are Linear, Bilinear, Trilinear");
+      addField("UseMips", TypeBool, Offset(UseMips, AssetImportConfig), "Indicates if images imported with this configuration utilize mipmaps");
+
+      addField("IsHDR", TypeBool, Offset(IsHDR, AssetImportConfig), "Indicates if images imported with this configuration are in an HDR format");
+      addField("Scaling", TypeF32, Offset(Scaling, AssetImportConfig), "Indicates what amount of scaling images imported with this configuration use");
+      addField("ImagesCompressed", TypeBool, Offset(ImagesCompressed, AssetImportConfig), "Indicates if images imported with this configuration are compressed");
+      addField("GenerateMaterialOnImport", TypeBool, Offset(GenerateMaterialOnImport, AssetImportConfig), "Indicates if images imported with this configuration generate a parent material for it as well");
+   endGroup("Images");
+
+   addGroup("Sounds");
+      addField("importSounds", TypeBool, Offset(importSounds, AssetImportConfig), "Indicates if sounds are imported with this configuration");
+      addField("VolumeAdjust", TypeF32, Offset(VolumeAdjust, AssetImportConfig), "Indicates what amount the volume is adjusted on sounds imported with this configuration");
+      addField("PitchAdjust", TypeF32, Offset(PitchAdjust, AssetImportConfig), "Indicates what amount the pitch is adjusted on sounds imported with this configuration");
+      addField("SoundsCompressed", TypeBool, Offset(SoundsCompressed, AssetImportConfig), "Indicates if sounds imported with this configuration are compressed");
+   endGroup("Sounds");
+}
+
+void AssetImportConfig::loadImportConfig(Settings* configSettings, String configName)
+{
+   //General
+   DuplicatAutoResolution = configSettings->value(String(configName + "/General/DuplicatAutoResolution").c_str());
+   WarningsAsErrors = dAtob(configSettings->value(String(configName + "/General/WarningsAsErrors").c_str()));
+   PreventImportWithErrors = dAtob(configSettings->value(String(configName + "/General/PreventImportWithErrors").c_str()));
+   AutomaticallyPromptMissingFiles = dAtob(configSettings->value(String(configName + "/General/AutomaticallyPromptMissingFiles").c_str()));
+
+   //Meshes
+   ImportMesh = dAtob(configSettings->value(String(configName + "/Meshes/ImportMesh").c_str()));
+   DoUpAxisOverride = dAtob(configSettings->value(String(configName + "/Meshes/DoUpAxisOverride").c_str()));
+   UpAxisOverride = configSettings->value(String(configName + "/Meshes/UpAxisOverride").c_str());
+   DoScaleOverride = dAtob(configSettings->value(String(configName + "/Meshes/DoScaleOverride").c_str()));
+   ScaleOverride = dAtof(configSettings->value(String(configName + "/Meshes/ScaleOverride").c_str()));
+   IgnoreNodeScale = dAtob(configSettings->value(String(configName + "/Meshes/IgnoreNodeScale").c_str()));
+   AdjustCenter = dAtob(configSettings->value(String(configName + "/Meshes/AdjustCenter").c_str()));
+   AdjustFloor = dAtob(configSettings->value(String(configName + "/Meshes/AdjustFloor").c_str()));
+   CollapseSubmeshes = dAtob(configSettings->value(String(configName + "/Meshes/CollapseSubmeshes").c_str()));
+   LODType = configSettings->value(String(configName + "/Meshes/LODType").c_str());
+   ImportedNodes = configSettings->value(String(configName + "/Meshes/ImportedNodes").c_str());
+   IgnoreNodes = configSettings->value(String(configName + "/Meshes/IgnoreNodes").c_str());
+   ImportMeshes = configSettings->value(String(configName + "/Meshes/ImportMeshes").c_str());
+   IgnoreMeshes = configSettings->value(String(configName + "/Meshes/IgnoreMeshes").c_str());
+
+   //Assimp/Collada
+   convertLeftHanded = dAtob(configSettings->value(String(configName + "/Meshes/convertLeftHanded").c_str()));
+   calcTangentSpace = dAtob(configSettings->value(String(configName + "/Meshes/calcTangentSpace").c_str()));
+   removeRedundantMats = dAtob(configSettings->value(String(configName + "/Meshes/removeRedundantMats").c_str()));
+   genUVCoords = dAtob(configSettings->value(String(configName + "/Meshes/genUVCoords").c_str()));
+   TransformUVs = dAtob(configSettings->value(String(configName + "/Meshes/TransformUVs").c_str()));
+   flipUVCoords = dAtob(configSettings->value(String(configName + "/Meshes/flipUVCoords").c_str()));
+   findInstances = dAtob(configSettings->value(String(configName + "/Meshes/findInstances").c_str()));
+   limitBoneWeights = dAtob(configSettings->value(String(configName + "/Meshes/limitBoneWeights").c_str()));
+   JoinIdenticalVerts = dAtob(configSettings->value(String(configName + "/Meshes/JoinIdenticalVerts").c_str()));
+   reverseWindingOrder = dAtob(configSettings->value(String(configName + "/Meshes/reverseWindingOrder").c_str()));
+   invertNormals = dAtob(configSettings->value(String(configName + "/Meshes/invertNormals").c_str()));
+
+   //Materials
+   ImportMaterials = dAtob(configSettings->value(String(configName + "/Materials/ImportMaterials").c_str()));
+   CreatePBRConfig = dAtob(configSettings->value(String(configName + "/Materials/CreatePBRConfig").c_str()));
+   UseDiffuseSuffixOnOriginImage = dAtob(configSettings->value(String(configName + "/Materials/UseDiffuseSuffixOnOriginImage").c_str()));
+   UseExistingMaterials = dAtob(configSettings->value(String(configName + "/Materials/UseExistingMaterials").c_str()));
+   IgnoreMaterials = configSettings->value(String(configName + "/Materials/IgnoreMaterials").c_str());
+   PopulateMaterialMaps = dAtob(configSettings->value(String(configName + "/Materials/invertPopulateMaterialMapsNormals").c_str()));
+
+   //Animations
+   ImportAnimations = dAtob(configSettings->value(String(configName + "/Animations/ImportAnimations").c_str()));
+   SeparateAnimations = dAtob(configSettings->value(String(configName + "/Animations/SeparateAnimations").c_str()));
+   SeparateAnimationPrefix = configSettings->value(String(configName + "/Animations/SeparateAnimationPrefix").c_str());
+   animTiming = configSettings->value(String(configName + "/Animations/animTiming").c_str());
+   animFPS = dAtof(configSettings->value(String(configName + "/Animations/animFPS").c_str()));
+
+   //Collisions
+   GenerateCollisions = dAtob(configSettings->value(String(configName + "/Collision/GenerateCollisions").c_str()));
+   GenCollisionType = configSettings->value(String(configName + "/Collision/GenCollisionType").c_str());
+   CollisionMeshPrefix = configSettings->value(String(configName + "/Collision/CollisionMeshPrefix").c_str());
+   GenerateLOSCollisions = dAtob(configSettings->value(String(configName + "/Collision/GenerateLOSCollisions").c_str()));
+   GenLOSCollisionType = configSettings->value(String(configName + "/Collision/GenLOSCollisionType").c_str());
+   LOSCollisionMeshPrefix = configSettings->value(String(configName + "/Collision/LOSCollisionMeshPrefix").c_str());
+
+   //Images
+   importImages = dAtob(configSettings->value(String(configName + "/Images/importImages").c_str()));
+   ImageType = configSettings->value(String(configName + "/Images/ImageType").c_str());
+   DiffuseTypeSuffixes = configSettings->value(String(configName + "/Images/DiffuseTypeSuffixes").c_str());
+   NormalTypeSuffixes = configSettings->value(String(configName + "/Images/NormalTypeSuffixes").c_str());
+   MetalnessTypeSuffixes = configSettings->value(String(configName + "/Images/MetalnessTypeSuffixes").c_str());
+   RoughnessTypeSuffixes = configSettings->value(String(configName + "/Images/RoughnessTypeSuffixes").c_str());
+   SmoothnessTypeSuffixes = configSettings->value(String(configName + "/Images/SmoothnessTypeSuffixes").c_str());
+   AOTypeSuffixes = configSettings->value(String(configName + "/Images/AOTypeSuffixes").c_str());
+   PBRTypeSuffixes = configSettings->value(String(configName + "/Images/PBRTypeSuffixes").c_str());
+   TextureFilteringMode = configSettings->value(String(configName + "/Images/TextureFilteringMode").c_str());
+   UseMips = dAtob(configSettings->value(String(configName + "/Images/UseMips").c_str()));
+   IsHDR = dAtob(configSettings->value(String(configName + "/Images/IsHDR").c_str()));
+   Scaling = dAtof(configSettings->value(String(configName + "/Images/Scaling").c_str()));
+   ImagesCompressed = dAtob(configSettings->value(String(configName + "/Images/Compressed").c_str()));
+   GenerateMaterialOnImport = dAtob(configSettings->value(String(configName + "/Images/GenerateMaterialOnImport").c_str()));
+
+   //Sounds
+   VolumeAdjust = dAtof(configSettings->value(String(configName + "/Sounds/VolumeAdjust").c_str()));
+   PitchAdjust = dAtof(configSettings->value(String(configName + "/Sounds/PitchAdjust").c_str()));
+   SoundsCompressed = dAtob(configSettings->value(String(configName + "/Sounds/Compressed").c_str()));
+}
+
+ConsoleDocClass(AssetImportObject,
+   "@brief Defines properties for an AssetImportObject object.\n"
+   "@AssetImportObject is a SimObject derived object intended to act as a stand-in for the to-be imported objects.\n"
+   "@It contains important info such as dependencies, if it's been processed, any error/status issues and the originating file\n"
+   "@or if it's been programmatically generated as part of the import process.\n\n"
+   "@ingroup Assets\n"
+);
+
+IMPLEMENT_CONOBJECT(AssetImportObject);
+
+AssetImportObject::AssetImportObject() :
+   dirty(false),
+   skip(false),
+   processed(false),
+   generatedAsset(false),
+   parentAssetItem(nullptr),
+   tamlFilePath(""),
+   imageSuffixType(""),
+   shapeInfo(nullptr)
+{
+
+}
+
+AssetImportObject::~AssetImportObject()
+{
+
+}
+
+void AssetImportObject::initPersistFields()
+{
+   Parent::initPersistFields();
+
+   addField("assetType", TypeString, Offset(assetType, AssetImportObject), "What type is the importing asset");
+   addField("filePath", TypeFilename, Offset(filePath, AssetImportObject), "What is the source file path of the importing asset");
+   addField("assetName", TypeString, Offset(assetName, AssetImportObject), "What is the asset's name");
+   addField("cleanAssetName", TypeString, Offset(cleanAssetName, AssetImportObject), "What is the original, unmodified by processing, asset name");
+   addField("status", TypeString, Offset(status, AssetImportObject), "What is the current status of this asset item in it's import process");
+   addField("statusType", TypeString, Offset(statusType, AssetImportObject), "If there is a warning or error status, what type is the condition for this asset item");
+   addField("statusInfo", TypeString, 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", TypeString, Offset(tamlFilePath, AssetImportObject), "What is the ultimate asset taml file path for this import item");
+
+   addField("imageSuffixType", TypeString, Offset(imageSuffixType, AssetImportObject), "Specific to ImageAsset type. What is the image asset's suffix type. Options are: Albedo, Normal, Roughness, AO, Metalness, PBRConfig");
+
+   addField("shapeInfo", TYPEID< GuiTreeViewCtrl >(), Offset(shapeInfo, AssetImportObject), "Specific to ShapeAsset type. Processed information about the shape file. Contains numbers and lists of meshes, materials and animations");
+}
+
+ConsoleDocClass(AssetImporter,
+   "@brief Defines properties for an AssetImportObject object.\n"
+   "@AssetImportObject is a SimObject derived object intended to act as a stand-in for the to-be imported objects.\n"
+   "@It contains important info such as dependencies, if it's been processed, any error/status issues and the originating file\n"
+   "@or if it's been programmatically generated as part of the import process.\n\n"
+   "@ingroup Assets\n"
+);
+
+IMPLEMENT_CONOBJECT(AssetImporter);
+
+AssetImporter::AssetImporter() :
+   importIssues(false),
+   isReimport(false),
+   assetHeirarchyChanged(false),
+   importLogBuffer("")
+{
+}
+
+AssetImporter::~AssetImporter()
+{
+
+}
+
+void AssetImporter::initPersistFields()
+{
+   Parent::initPersistFields();
+}
+
+//
+// Utility Functions
+//
+
+AssetImportObject* AssetImporter::addImportingFile(Torque::Path filePath)
+{
+   String assetType = getAssetTypeByFile(filePath);
+
+   if (assetType.isEmpty())
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is of an unrecognized/unsupported type.", filePath.getFullPath().c_str());
+      activityLog.push_back(importLogBuffer);
+      return nullptr;
+   }
+
+   AssetImportObject* newAssetItem = addImportingAsset(assetType, filePath, nullptr, "");
+
+   originalImportingFiles.push_back(filePath);
+
+   return newAssetItem;
+}
+
+AssetImportObject* AssetImporter::addImportingAsset(String assetType, Torque::Path filePath, AssetImportObject* parentItem, String assetNameOverride)
+{
+   String assetName;
+
+   //In some cases(usually generated assets on import, like materials) we'll want to specifically define the asset name instead of peeled from the filePath
+   if (assetNameOverride.isNotEmpty())
+      assetName = assetNameOverride;
+   else
+      assetName = filePath.getFileName();
+
+   AssetImportObject* assetImportObj = new AssetImportObject();
+   assetImportObj->registerObject();
+
+   assetImportObj->assetType = assetType;
+   assetImportObj->filePath = filePath;
+   assetImportObj->assetName = assetName;
+   assetImportObj->cleanAssetName = assetName;
+   assetImportObj->moduleName = targetModuleId;
+   assetImportObj->status = "";
+   assetImportObj->statusType = "";
+   assetImportObj->statusInfo = "";
+
+   assetImportObj->dirty = false;
+   assetImportObj->skip = false;
+   assetImportObj->processed = false;
+   assetImportObj->generatedAsset = false;
+
+   if (parentItem != nullptr)
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Added Child Importing Asset to %s", parentItem->assetName.c_str());
+      activityLog.push_back(importLogBuffer);
+
+      parentItem->childAssetItems.push_back(assetImportObj);
+      assetImportObj->parentAssetItem = parentItem;
+   }
+   else
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Added Importing Asset");
+      activityLog.push_back(importLogBuffer);
+   }
+
+   dSprintf(importLogBuffer, sizeof(importLogBuffer), "   Asset Info: Name: %s | Type: %s", assetImportObj->assetName.c_str(), assetImportObj->assetType.c_str());
+   activityLog.push_back(importLogBuffer);
+
+   if (!filePath.isEmpty())
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "   File: %s", filePath.getFullPath().c_str());
+      activityLog.push_back(importLogBuffer);
+   }
+
+   return assetImportObj;
+}
+
+void AssetImporter::deleteImportingAsset(AssetImportObject* assetItem)
+{
+   assetItem->skip = true;
+
+   //log it
+   dSprintf(importLogBuffer, sizeof(importLogBuffer), "Deleting Importing Asset %s and all it's child items", assetItem->assetName.c_str());
+   activityLog.push_back(importLogBuffer);
+}
+
+AssetImportObject* AssetImporter::findImportingAssetByName(String assetName, AssetImportObject* assetItem)
+{
+   if (assetItem == nullptr)
+   {
+      for (U32 i = 0; i < importingAssets.size(); i++)
+      {
+         if (importingAssets[i]->cleanAssetName == assetName)
+         {
+            return importingAssets[i];
+         }
+
+         //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
+   {
+      //this is the child recursing section
+      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+      {
+         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 nullptr;
+}
+
+ModuleDefinition* AssetImporter::getModuleFromPath(Torque::Path filePath)
+{
+   U32 folderCount = StringUnit::getUnitCount(filePath.getPath().c_str(), "/");
+
+   for (U32 i = 0; i < folderCount; i++)
+   {
+      String folderName = StringUnit::getUnit(filePath.getPath().c_str(), i, "/");
+
+      ModuleDefinition* moduleDef = ModuleDatabase.findModule(folderName.c_str(), 1);
+      if (moduleDef != nullptr)
+         return moduleDef;
+   }
+
+   return nullptr;
+}
+
+String AssetImporter::parseImageSuffixes(String assetName, String* suffixType)
+{
+   //Here, we loop over our different suffix lists progressively.
+   //This lets us walk through a list of suffixes in the Import Config, such as DiffuseTypeSuffixes
+   //And then iterate over the delinated list of items within it to look for a match.
+   //If we don't find a match, we then increment our list switch index and scan through the next list.
+   U32 suffixTypeIdx = 0;
+   while (suffixTypeIdx < 6)
+   {
+      String suffixList;
+      switch (suffixTypeIdx)
+      {
+         case 0:
+            suffixList = activeImportConfig.DiffuseTypeSuffixes;
+            suffixType->insert(0, "Albedo", 10);
+            break;
+         case 1:
+            suffixList = activeImportConfig.NormalTypeSuffixes;
+            suffixType->insert(0, "Normal", 10);
+            break;
+         case 2:
+            suffixList = activeImportConfig.RoughnessTypeSuffixes;
+            suffixType->insert(0, "Roughness", 10);
+            break;
+         case 3:
+            suffixList = activeImportConfig.AOTypeSuffixes;
+            suffixType->insert(0, "AO", 10);
+            break;
+         case 4:
+            suffixList = activeImportConfig.MetalnessTypeSuffixes;
+            suffixType->insert(0, "Metalness", 10);
+            break;
+         case 5:
+            suffixList = activeImportConfig.PBRTypeSuffixes;
+            suffixType->insert(0, "PBRConfig", 10);
+            break;
+         default:
+            suffixList = "";
+      }
+
+      suffixTypeIdx++;
+
+      U32 suffixCount = StringUnit::getUnitCount(suffixList, ",;");
+      for (U32 i = 0; i < suffixCount; i++)
+      {
+         String suffix = StringUnit::getUnit(suffixList, i, ",;");
+         String searchSuffix = String("*") + suffix;
+         if (FindMatch::isMatch(searchSuffix.c_str(), assetName.c_str(), false))
+         {
+            //We have a match, so indicate as such
+            return suffix;
+         }
+      }
+   }
+
+   return "";
+}
+
+String AssetImporter::getAssetTypeByFile(Torque::Path filePath)
+{
+   String fileExt = filePath.getExtension();
+
+   if (fileExt == String("png") || fileExt == String("jpg") || fileExt == String("jpeg") || fileExt == String("dds"))
+      return "ImageAsset";
+   else if (fileExt == String("dae") || fileExt == String("fbx") || fileExt == String("blend") || fileExt == String("obj") || fileExt == String("dts") || fileExt == String("gltf") || fileExt == String("gltb"))
+      return "ShapeAsset";
+   else if (fileExt == String("dsq"))
+      return "ShapeAnimationAsset";
+   else if (fileExt == String("ogg") || fileExt == String("wav") || fileExt == String("mp3"))
+      return "SoundAsset";
+   else if (fileExt == String("zip"))
+      return "Zip";
+   else if (fileExt.isEmpty())
+      return "Folder";
+
+   return "";
+}
+
+void AssetImporter::resetImportSession()
+{
+   importingAssets.clear();
+   activityLog.clear();
+
+   for (U32 i = 0; i < originalImportingFiles.size(); i++)
+   {
+      addImportingFile(originalImportingFiles[i]);
+   }
+}
+
+S32 AssetImporter::getActivityLogLineCount()
+{
+   return activityLog.size();
+}
+
+String AssetImporter::getActivityLogLine(U32 line)
+{
+   if (line >= activityLog.size())
+      return "";
+
+   return activityLog[line];
+}
+
+void AssetImporter::dumpActivityLog()
+{
+   for (U32 i = 0; i < activityLog.size(); i++)
+   {
+      Con::printf(activityLog[i].c_str());
+   }
+}
+
+S32 AssetImporter::getAssetItemCount()
+{
+   return importingAssets.size();
+}
+
+AssetImportObject* AssetImporter::getAssetItem(U32 index)
+{
+   if (index >= importingAssets.size())
+      return nullptr;
+
+   return importingAssets[index];
+}
+
+S32 AssetImporter::getAssetItemChildCount(AssetImportObject* assetItem)
+{
+   return assetItem->childAssetItems.size();
+}
+
+AssetImportObject* AssetImporter::getAssetItemChild(AssetImportObject* assetItem, U32 index)
+{
+   if (index >= assetItem->childAssetItems.size())
+      return nullptr;
+
+   return assetItem->childAssetItems[index];
+}
+//
+// Processing
+//
+// Helper struct for counting nodes, meshes and polygons down through the scene
+// hierarchy
+struct SceneStats
+{
+   S32 numNodes;
+   S32 numMeshes;
+   S32 numPolygons;
+   S32 numMaterials;
+   S32 numLights;
+   S32 numClips;
+
+   SceneStats() : numNodes(0), numMeshes(0), numPolygons(0), numMaterials(0), numLights(0), numClips(0) { }
+};
+
+// Recurse through the <visual_scene> adding nodes and geometry to the GuiTreeView control
+static void processNode(GuiTreeViewCtrl* tree, domNode* node, S32 parentID, SceneStats& stats)
+{
+   stats.numNodes++;
+   S32 nodeID = tree->insertItem(parentID, _GetNameOrId(node), "node", "", 0, 0);
+
+   // Update mesh and poly counts
+   for (S32 i = 0; i < node->getContents().getCount(); i++)
+   {
+      domGeometry* geom = 0;
+      const char* elemName = "";
+
+      daeElement* child = node->getContents()[i];
+      switch (child->getElementType())
+      {
+      case COLLADA_TYPE::INSTANCE_GEOMETRY:
+      {
+         domInstance_geometry* instgeom = daeSafeCast<domInstance_geometry>(child);
+         if (instgeom)
+         {
+            geom = daeSafeCast<domGeometry>(instgeom->getUrl().getElement());
+            elemName = _GetNameOrId(geom);
+         }
+         break;
+      }
+
+      case COLLADA_TYPE::INSTANCE_CONTROLLER:
+      {
+         domInstance_controller* instctrl = daeSafeCast<domInstance_controller>(child);
+         if (instctrl)
+         {
+            domController* ctrl = daeSafeCast<domController>(instctrl->getUrl().getElement());
+            elemName = _GetNameOrId(ctrl);
+            if (ctrl && ctrl->getSkin())
+               geom = daeSafeCast<domGeometry>(ctrl->getSkin()->getSource().getElement());
+            else if (ctrl && ctrl->getMorph())
+               geom = daeSafeCast<domGeometry>(ctrl->getMorph()->getSource().getElement());
+         }
+         break;
+      }
+
+      case COLLADA_TYPE::INSTANCE_LIGHT:
+         stats.numLights++;
+         tree->insertItem(nodeID, _GetNameOrId(node), "light", "", 0, 0);
+         break;
+      }
+
+      if (geom && geom->getMesh())
+      {
+         const char* name = _GetNameOrId(node);
+         if (dStrEqual(name, "null") || dStrEndsWith(name, "PIVOT"))
+            name = _GetNameOrId(daeSafeCast<domNode>(node->getParent()));
+
+         stats.numMeshes++;
+         tree->insertItem(nodeID, name, "mesh", "", 0, 0);
+
+         for (S32 j = 0; j < geom->getMesh()->getTriangles_array().getCount(); j++)
+            stats.numPolygons += geom->getMesh()->getTriangles_array()[j]->getCount();
+         for (S32 j = 0; j < geom->getMesh()->getTristrips_array().getCount(); j++)
+            stats.numPolygons += geom->getMesh()->getTristrips_array()[j]->getCount();
+         for (S32 j = 0; j < geom->getMesh()->getTrifans_array().getCount(); j++)
+            stats.numPolygons += geom->getMesh()->getTrifans_array()[j]->getCount();
+         for (S32 j = 0; j < geom->getMesh()->getPolygons_array().getCount(); j++)
+            stats.numPolygons += geom->getMesh()->getPolygons_array()[j]->getCount();
+         for (S32 j = 0; j < geom->getMesh()->getPolylist_array().getCount(); j++)
+            stats.numPolygons += geom->getMesh()->getPolylist_array()[j]->getCount();
+      }
+   }
+
+   // Recurse into child nodes
+   for (S32 i = 0; i < node->getNode_array().getCount(); i++)
+      processNode(tree, node->getNode_array()[i], nodeID, stats);
+
+   for (S32 i = 0; i < node->getInstance_node_array().getCount(); i++)
+   {
+      domInstance_node* instnode = node->getInstance_node_array()[i];
+      domNode* dNode = daeSafeCast<domNode>(instnode->getUrl().getElement());
+      if (dNode)
+         processNode(tree, dNode, nodeID, stats);
+   }
+}
+
+static bool enumColladaForImport(const char* shapePath, GuiTreeViewCtrl* tree, bool loadCachedDts)
+{
+   // Check if a cached DTS is available => no need to import the collada file
+   // if we can load the DTS instead
+   Torque::Path path(shapePath);
+   if (loadCachedDts && ColladaShapeLoader::canLoadCachedDTS(path))
+      return false;
+
+   // Check if this is a Sketchup file (.kmz) and if so, mount the zip filesystem
+   // and get the path to the DAE file.
+   String mountPoint;
+   Torque::Path daePath;
+   bool isSketchup = ColladaShapeLoader::checkAndMountSketchup(path, mountPoint, daePath);
+
+   // Load the Collada file into memory
+   domCOLLADA* root = ColladaShapeLoader::getDomCOLLADA(daePath);
+   if (!root)
+   {
+      TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Load complete");
+      return false;
+   }
+
+   if (isSketchup)
+   {
+      // Unmount the zip if we mounted it
+      Torque::FS::Unmount(mountPoint);
+   }
+
+   // Initialize tree
+   tree->removeItem(0);
+   S32 nodesID = tree->insertItem(0, "Shape", "", "", 0, 0);
+   S32 matsID = tree->insertItem(0, "Materials", "", "", 0, 0);
+   S32 animsID = tree->insertItem(0, "Animations", "", "", 0, 0);
+
+   SceneStats stats;
+
+   // Query DOM for shape summary details
+   for (S32 i = 0; i < root->getLibrary_visual_scenes_array().getCount(); i++)
+   {
+      const domLibrary_visual_scenes* libScenes = root->getLibrary_visual_scenes_array()[i];
+      for (S32 j = 0; j < libScenes->getVisual_scene_array().getCount(); j++)
+      {
+         const domVisual_scene* visualScene = libScenes->getVisual_scene_array()[j];
+         for (S32 k = 0; k < visualScene->getNode_array().getCount(); k++)
+            processNode(tree, visualScene->getNode_array()[k], nodesID, stats);
+      }
+   }
+
+   // Get material count
+   for (S32 i = 0; i < root->getLibrary_materials_array().getCount(); i++)
+   {
+      const domLibrary_materials* libraryMats = root->getLibrary_materials_array()[i];
+      stats.numMaterials += libraryMats->getMaterial_array().getCount();
+      for (S32 j = 0; j < libraryMats->getMaterial_array().getCount(); j++)
+      {
+         domMaterial* mat = libraryMats->getMaterial_array()[j];
+         tree->insertItem(matsID, _GetNameOrId(mat), "", "", 0, 0);
+      }
+   }
+
+   // Get images count
+   for (S32 i = 0; i < root->getLibrary_images_array().getCount(); i++)
+   {
+      const domLibrary_images* libraryImages = root->getLibrary_images_array()[i];
+
+      for (S32 j = 0; j < libraryImages->getImage_array().getCount(); j++)
+      {
+         domImage* img = libraryImages->getImage_array()[j];
+
+         S32 materialID = tree->findItemByName(_GetNameOrId(img));
+
+         if (materialID == 0)
+            continue;
+
+         tree->setItemValue(materialID, img->getInit_from()->getValue().str().c_str());
+      }
+   }
+
+   // Get animation count
+   for (S32 i = 0; i < root->getLibrary_animation_clips_array().getCount(); i++)
+   {
+      const domLibrary_animation_clips* libraryClips = root->getLibrary_animation_clips_array()[i];
+      stats.numClips += libraryClips->getAnimation_clip_array().getCount();
+      for (S32 j = 0; j < libraryClips->getAnimation_clip_array().getCount(); j++)
+      {
+         domAnimation_clip* clip = libraryClips->getAnimation_clip_array()[j];
+         tree->insertItem(animsID, _GetNameOrId(clip), "animation", "", 0, 0);
+      }
+   }
+   if (stats.numClips == 0)
+   {
+      // No clips => check if there are any animations (these will be added to a default clip)
+      for (S32 i = 0; i < root->getLibrary_animations_array().getCount(); i++)
+      {
+         const domLibrary_animations* libraryAnims = root->getLibrary_animations_array()[i];
+         if (libraryAnims->getAnimation_array().getCount())
+         {
+            stats.numClips = 1;
+            tree->insertItem(animsID, "ambient", "animation", "", 0, 0);
+            break;
+         }
+      }
+   }
+
+   // Extract the global scale and up_axis from the top level <asset> element,
+   F32 unit = 1.0f;
+   domUpAxisType upAxis = UPAXISTYPE_Z_UP;
+   if (root->getAsset()) {
+      if (root->getAsset()->getUnit())
+         unit = root->getAsset()->getUnit()->getMeter();
+      if (root->getAsset()->getUp_axis())
+         upAxis = root->getAsset()->getUp_axis()->getValue();
+   }
+
+   TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Load complete");
+
+   // Store shape information in the tree control
+   tree->setDataField(StringTable->insert("_nodeCount"), 0, avar("%d", stats.numNodes));
+   tree->setDataField(StringTable->insert("_meshCount"), 0, avar("%d", stats.numMeshes));
+   tree->setDataField(StringTable->insert("_polygonCount"), 0, avar("%d", stats.numPolygons));
+   tree->setDataField(StringTable->insert("_materialCount"), 0, avar("%d", stats.numMaterials));
+   tree->setDataField(StringTable->insert("_lightCount"), 0, avar("%d", stats.numLights));
+   tree->setDataField(StringTable->insert("_animCount"), 0, avar("%d", stats.numClips));
+   tree->setDataField(StringTable->insert("_unit"), 0, avar("%g", unit));
+
+   if (upAxis == UPAXISTYPE_X_UP)
+      tree->setDataField(StringTable->insert("_upAxis"), 0, "X_AXIS");
+   else if (upAxis == UPAXISTYPE_Y_UP)
+      tree->setDataField(StringTable->insert("_upAxis"), 0, "Y_AXIS");
+   else
+      tree->setDataField(StringTable->insert("_upAxis"), 0, "Z_AXIS");
+
+   char shapesStr[16];
+   dSprintf(shapesStr, 16, "%i", stats.numMeshes);
+   char materialsStr[16];
+   dSprintf(materialsStr, 16, "%i", stats.numMaterials);
+   char animationsStr[16];
+   dSprintf(animationsStr, 16, "%i", stats.numClips);
+
+   tree->setItemValue(nodesID, StringTable->insert(shapesStr));
+   tree->setItemValue(matsID, StringTable->insert(materialsStr));
+   tree->setItemValue(animsID, StringTable->insert(animationsStr));
+
+   return true;
+}
+
+void AssetImporter::processImportAssets(AssetImportObject* assetItem)
+{
+   if (assetItem == nullptr)
+   {
+      assetHeirarchyChanged = false;
+
+      for (U32 i = 0; i < importingAssets.size(); i++)
+      {
+         AssetImportObject* item = importingAssets[i];
+         if (item->skip)
+            continue;
+
+         if (!item->processed)
+         {
+            //Sanitize before modifying our asset name(suffix additions, etc)
+            if (item->assetName != item->cleanAssetName)
+               item->assetName = item->cleanAssetName;
+
+            //handle special pre-processing here for any types that need it
+
+            //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);*/
+
+            item->processed = true;
+         }
+
+         //try recusing on the children(if any)
+         processImportAssets(item);
+      }
+   }
+   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;
+
+         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 (childItem->assetType == String("SoundAsset"))
+               SoundAsset::prepareAssetForImport(this, childItem);*/
+            else if (childItem->assetType == String("MaterialAsset"))
+               processMaterialAsset(childItem);
+            /*else if (childItem->assetType == String("ShapeAnimationAsset"))
+               ShapeAnimationAsset::prepareAssetForImport(this, childItem);*/
+
+            childItem->processed = true;
+         }
+
+         //try recusing on the children(if any)
+         processImportAssets(childItem);
+      }
+   }
+
+   //If our hierarchy changed, it's because we did so during processing
+   //so we'll loop back through again until everything has been processed
+   if (assetHeirarchyChanged)
+      processImportAssets();
+}
+
+void AssetImporter::processImageAsset(AssetImportObject* assetItem)
+{
+   dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Image for Import: %s", assetItem->assetName.c_str());
+   activityLog.push_back(importLogBuffer);
+
+   if ((activeImportConfig.GenerateMaterialOnImport && assetItem->parentAssetItem == nullptr) || assetItem->parentAssetItem != nullptr)
+   {
+      //find our suffix match, if any
+      String noSuffixName = assetItem->assetName;
+      String suffixType;
+      String suffix = parseImageSuffixes(assetItem->assetName, &suffixType);
+      if (suffix.isNotEmpty())
+      {
+         assetItem->imageSuffixType = suffixType;
+         S32 suffixPos =assetItem->assetName.find(suffix, 0, String::NoCase|String::Left);
+         noSuffixName = assetItem->assetName.substr(0, suffixPos);
+      }
+
+      //We try to automatically populate materials under the naming convention: materialName: Rock, image maps: Rock_Albedo, Rock_Normal, etc
+
+      AssetImportObject* materialAsset = findImportingAssetByName(noSuffixName);
+      if (materialAsset != nullptr && materialAsset->assetType != String("MaterialAsset"))
+      {
+         //We may have a situation where an asset matches the no-suffix name, but it's not a material asset. Ignore this
+         //asset item for now
+         materialAsset = nullptr;
+      }
+
+      //If we didn't find a matching material asset in our current items, we'll make one now
+      if (materialAsset == nullptr)
+      {
+         if (!assetItem->filePath.isEmpty())
+         {
+            materialAsset = addImportingAsset("MaterialAsset", "", nullptr, noSuffixName);
+            //Add the material into the primary list of importing assets
+            importingAssets.push_back(materialAsset);
+         }
+      }
+
+      //Not that, one way or another, we have the generated material asset, lets move on to associating our image with it
+      if (materialAsset != nullptr && materialAsset != assetItem->parentAssetItem)
+      {
+         if (assetItem->parentAssetItem != nullptr)
+         {
+            //If the image had an existing parent, it gets removed from that parent's child item list
+            assetItem->parentAssetItem->childAssetItems.remove(assetItem);
+         }
+         else
+         {
+            //If it didn't have one, we're going to pull it from the importingAssets list
+            importingAssets.remove(assetItem);
+         }
+
+         //Now we can add it to the correct material asset
+         materialAsset->childAssetItems.push_back(assetItem);
+         assetItem->parentAssetItem = materialAsset;
+
+         assetHeirarchyChanged = true;
+      }
+
+      //Now to do some cleverness. If we're generating a material, we can parse like assets being imported(similar filenames) but different suffixes
+      //If we find these, we'll just populate into the original's material
+
+      //if we need to append the diffuse suffix and indeed didn't find a suffix on the name, do that here
+      if (suffixType.isEmpty())
+      {
+         if (activeImportConfig.UseDiffuseSuffixOnOriginImage)
+         {
+            String diffuseToken = StringUnit::getUnit(activeImportConfig.DiffuseTypeSuffixes, 0, ",;");
+            assetItem->assetName = assetItem->assetName + diffuseToken;
+         }
+         else
+         {
+            //We need to ensure that our image asset doesn't match the same name as the material asset, so if we're not trying to force the diffuse suffix
+            //we'll give it a generic one
+            if (materialAsset->assetName.compare(assetItem->assetName) == 0)
+            {
+               assetItem->assetName = assetItem->assetName + "_image";
+            }
+         }
+
+         suffixType = "Albedo";
+      }
+      
+      if (suffixType.isNotEmpty())
+      {
+         assetItem->imageSuffixType = suffixType;
+
+         //otherwise, if we have some sort of suffix, we'll want to figure out if we've already got an existing material, and should append to it  
+         if (activeImportConfig.PopulateMaterialMaps)
+         {
+            
+         }
+      }
+   }
+
+   assetItem->processed = true;
+}
+
+void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
+{
+   dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Material for Import: %s", assetItem->assetName.c_str());
+   activityLog.push_back(importLogBuffer);
+
+   String filePath = assetItem->filePath.getFullPath();
+   String fileName = assetItem->filePath.getFileName();
+   String fileExt = assetItem->filePath.getExtension();
+   const char* assetName = assetItem->assetName.c_str();
+
+   assetItem->generatedAsset = true;
+
+   if (activeImportConfig.IgnoreMaterials.isNotEmpty())
+   {
+      U32 ignoredMatNameCount = StringUnit::getUnitCount(activeImportConfig.IgnoreMaterials, ".;");
+      for (U32 i = 0; i < ignoredMatNameCount; i++)
+      {
+         String ignoredName = StringUnit::getUnit(activeImportConfig.IgnoreMaterials, i, ".;");
+         if (FindMatch::isMatch(ignoredName.c_str(), assetName, false))
+         {
+            assetItem->skip = true;
+
+            dSprintf(importLogBuffer, sizeof(importLogBuffer), "Material %s has been ignored due to it's name being listed in the IgnoreMaterials list in the Import Config.", assetItem->assetName.c_str());
+            activityLog.push_back(importLogBuffer);
+            return;
+         }
+      }
+   }
+
+   if (activeImportConfig.PopulateMaterialMaps)
+   {
+      //If we're trying to populate the rest of our material maps, we need to go looking
+   }
+   
+   assetItem->processed = true;
+}
+
+void AssetImporter::processShapeAsset(AssetImportObject* assetItem)
+{
+   dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Shape for Import: %s", assetItem->assetName.c_str());
+   activityLog.push_back(importLogBuffer);
+
+   String filePath = assetItem->filePath.getFullPath();
+   String fileName = assetItem->filePath.getFileName();
+   String fileExt = assetItem->filePath.getExtension();
+   const char* assetName = assetItem->assetName.c_str();
+
+   if (assetItem->shapeInfo == nullptr)
+   {
+      GuiTreeViewCtrl* shapeInfo = new GuiTreeViewCtrl();
+      shapeInfo->registerObject();
+
+      if (fileExt.compare("dae") == 0)
+      {
+         enumColladaForImport(filePath, shapeInfo, false);
+      }
+      else
+      {
+         // Check if a cached DTS is available => no need to import the source file
+         // if we can load the DTS instead
+
+         AssimpShapeLoader loader;
+         loader.fillGuiTreeView(filePath.c_str(), shapeInfo);
+      }
+
+      assetItem->shapeInfo = shapeInfo;
+   }
+
+   S32 meshCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_meshCount"), nullptr));
+   S32 shapeItem = assetItem->shapeInfo->findItemByName("Meshes");
+
+   S32 animCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_animCount"), nullptr));
+   S32 animItem = assetItem->shapeInfo->findItemByName("Animations");
+
+   S32 materialCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_materialCount"), nullptr));
+   S32 matItem = assetItem->shapeInfo->findItemByName("Materials");
+
+   dSprintf(importLogBuffer, sizeof(importLogBuffer), "   Shape Info: Mesh Count: %i | Material Count: %i | Anim Count: %i", meshCount, animCount, materialCount);
+   activityLog.push_back(importLogBuffer);
+
+   if (activeImportConfig.ImportMesh && meshCount > 0)
+   {
+
+   }
+
+   if (activeImportConfig.ImportAnimations && animCount > 0)
+   {
+      //If we have animations but no meshes, then this is a pure animation file so we can swap the asset type here
+      if (meshCount == 0)
+      {
+         //assetItem->assetType = "ShapeAnimation";
+      }
+   }
+
+   if (activeImportConfig.ImportMaterials && materialCount > 0)
+   {
+      S32 materialId = assetItem->shapeInfo->getChildItem(matItem);
+      processShapeMaterialInfo(assetItem, materialId);
+
+      materialId = assetItem->shapeInfo->getNextSiblingItem(materialId);
+      while (materialId != 0)
+      {
+         processShapeMaterialInfo(assetItem, materialId);
+         materialId = assetItem->shapeInfo->getNextSiblingItem(materialId);
+      }
+   }
+
+   assetItem->processed = true;
+}
+
+void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 materialItemId)
+{
+   String matName = assetItem->shapeInfo->getItemText(materialItemId);
+
+   Torque::Path filePath = assetItem->shapeInfo->getItemValue(materialItemId);
+   if (filePath.getFullFileName().isNotEmpty())
+   {
+      if (!Platform::isFile(filePath.getFullFileName()))
+      {
+         //could be a stale path reference, such as if it was downloaded elsewhere. Trim to just the filename and see
+         //if we can find it there
+         String shapePathBase = assetItem->filePath.getPath();
+
+         String matFilePath = filePath.getFileName() + "." + filePath.getExtension();
+         //trim (not found) if needbe
+         /*
+         %suffixPos = strpos(strlwr(%filename), " (not found)", 0);
+         %filename = getSubStr(%filename, 0, %suffixPos);
+         */
+
+         String testFileName = shapePathBase + "/" + matFilePath;
+         if (Platform::isFile(testFileName))
+         {
+            filePath = testFileName;
+         }
+      }
+
+      AssetImportObject* matAssetItem = addImportingAsset("MaterialAsset", "", assetItem, matName);
+      addImportingAsset("ImageAsset", filePath, matAssetItem, "");
+   }
+   else
+   {
+      /*
+      //check to see if it's actually just a flat color
+      if(getWordCount(%filePath) == 4 && getWord(%filePath, 0) $= "Color:")
+      {
+         AssetBrowser.addImportingAsset("MaterialAsset", %matName, %assetItem);
+      }
+      else
+      {
+         //we need to try and find our material, since the shapeInfo wasn't able to find it automatically
+         %filePath = findImageFile(filePath(%assetItem.filePath), %matName);
+         if(%filePath !$= "" && isFile(%filePath))
+            AssetBrowser.addImportingAsset("MaterialAsset", %filePath, %assetItem);
+         else
+            AssetBrowser.addImportingAsset("MaterialAsset", filePath(%assetItem.filePath) @ "/" @ %matName, %assetItem);
+      }
+      */
+   }
+}
+
+//
+// Validation
+//
+
+bool AssetImporter::validateAssets()
+{
+   importIssues = false;
+
+   resetAssetValidationStatus();
+
+   for (U32 i = 0; i < importingAssets.size(); i++)
+   {
+      validateAsset(importingAssets[i]);
+      resolveAssetItemIssues(importingAssets[i]);
+   }
+
+   return importIssues;
+}
+
+void AssetImporter::validateAsset(AssetImportObject* assetItem)
+{
+   if (assetItem->skip)
+      return;
+
+   bool hasCollision = checkAssetForCollision(assetItem);
+
+   if (hasCollision)
+   {
+      importIssues = true;
+      return;
+   }
+
+   if (!isReimport)
+   {
+      AssetQuery aQuery;
+      U32 numAssetsFound = AssetDatabase.findAllAssets(&aQuery);
+
+      bool hasCollision = false;
+      for (U32 i = 0; i < numAssetsFound; i++)
+      {
+         StringTableEntry assetId = aQuery.mAssetList[i];
+
+         ModuleDefinition* moduleDef = AssetDatabase.getAssetModuleDefinition(assetId);
+
+         if (moduleDef->getModuleId() != StringTable->insert(targetModuleId.c_str()))
+            continue;
+
+         StringTableEntry assetName = AssetDatabase.getAssetName(assetId);
+
+         if (assetName == StringTable->insert(assetItem->assetName.c_str()))
+         {
+            hasCollision = true;
+            assetItem->status = "Error";
+            assetItem->statusType = "DuplicateAsset";
+            assetItem->statusInfo = "Duplicate asset names found within the target module!\nAsset \"" + assetItem->assetName + "\" of type \"" + assetItem->assetType + "\" has a matching name.\nPlease rename it and try again!";
+
+            //log it
+            dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Asset %s has an identically named asset in the target module.", assetItem->assetName.c_str());
+            activityLog.push_back(importLogBuffer);
+            break;
+         }
+      }
+   }
+
+   if (!assetItem->filePath.isEmpty() && !assetItem->generatedAsset && !Platform::isFile(assetItem->filePath.getFullPath().c_str()))
+   {
+      assetItem->status = "Error";
+      assetItem->statusType = "MissingFile";
+      assetItem->statusInfo = "Unable to find file to be imported with provided path: " + assetItem->filePath + "\n Please select a valid file.";
+
+      //log it
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Asset %s's file at %s was not found.", assetItem->assetName.c_str(), assetItem->filePath.getFullPath().c_str());
+      activityLog.push_back(importLogBuffer);
+   }
+
+   if (assetItem->status == String("Warning"))
+   {
+      if (activeImportConfig.WarningsAsErrors)
+      {
+         assetItem->status = "Error";
+
+         //log it
+         dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Import configuration has treated an import warning as an error.", assetItem->assetName.c_str());
+         activityLog.push_back(importLogBuffer);
+      }
+   }
+
+   if (assetItem->status == String("Error"))
+      importIssues = true;
+
+   for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+   {
+      validateAsset(assetItem->childAssetItems[i]);
+      resolveAssetItemIssues(assetItem->childAssetItems[i]);
+   }
+
+   return;
+}
+
+void AssetImporter::resetAssetValidationStatus(AssetImportObject* assetItem)
+{
+   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 = "";
+
+         //If it wasn't a match, try recusing on the children(if any)
+         resetAssetValidationStatus(importingAssets[i]);
+      }
+   }
+   else
+   {
+      //this is the child recursing section
+      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+      {
+         if (assetItem->childAssetItems[i]->skip)
+            continue;
+
+         assetItem->childAssetItems[i]->status = "";
+         assetItem->childAssetItems[i]->statusType = "";
+         assetItem->childAssetItems[i]->statusInfo = "";
+
+         //If it wasn't a match, try recusing on the children(if any)
+         resetAssetValidationStatus(assetItem->childAssetItems[i]);
+      }
+   }
+}
+
+bool AssetImporter::checkAssetForCollision(AssetImportObject* assetItemToCheck, AssetImportObject* assetItem)
+{
+   bool results = false;
+
+   if (assetItem == nullptr)
+   {
+      for (U32 i = 0; i < importingAssets.size(); i++)
+      {
+         if (importingAssets[i]->skip)
+            continue;
+
+         if ((assetItemToCheck->assetName.compare(importingAssets[i]->assetName) == 0) && (assetItemToCheck->getId() != importingAssets[i]->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 \"" + importingAssets[i]->assetName + "\" of the type \"" + importingAssets[i]->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(),
+                importingAssets[i]->assetName.c_str(), importingAssets[i]->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, importingAssets[i]);
+         if (results)
+            return results;
+      }
+   }
+   else
+   {
+      //this is the child recursing section
+      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+      {
+         if (assetItem->childAssetItems[i]->skip)
+            continue;
+
+         if ((assetItemToCheck->assetName.compare(assetItem->childAssetItems[i]->assetName) == 0) && (assetItemToCheck->getId() != assetItem->childAssetItems[i]->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.";
+
+            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(),
+               importingAssets[i]->assetName.c_str(), importingAssets[i]->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, assetItem->childAssetItems[i]);
+         if (results)
+            return results;
+      }
+   }
+
+   return results;
+}
+
+void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem)
+{
+   if (assetItem->statusType == String("DuplicateImportAsset") || assetItem->statusType == String("DuplicateAsset"))
+   {
+      String humanReadableReason = assetItem->statusType == String("DuplicateImportAsset") ? "Importing asset was duplicate of another importing asset" : "Importing asset was duplicate of an existing asset";
+
+      //get the config value for duplicateAutoResolution
+      if (activeImportConfig.DuplicatAutoResolution == String("AutoPrune"))
+      {
+         //delete the item
+         deleteImportingAsset(assetItem);
+
+         //log it's deletion
+         dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was autoprined due to %s as part of the Import Configuration", assetItem->assetName.c_str(), humanReadableReason.c_str());
+         activityLog.push_back(importLogBuffer);
+
+         importIssues = false;
+      }
+      else if (activeImportConfig.DuplicatAutoResolution == String("AutoRename"))
+      {
+         //Set trailing number
+         String renamedAssetName = assetItem->assetName;
+         renamedAssetName = Sim::getUniqueName(renamedAssetName.c_str());
+
+         //Log it's renaming
+         dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was renamed due to %s as part of the Import Configuration", assetItem->assetName.c_str(), humanReadableReason.c_str());
+         activityLog.push_back(importLogBuffer);
+
+         dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was renamed to %s", assetItem->assetName.c_str(), renamedAssetName.c_str());
+         activityLog.push_back(importLogBuffer);
+
+         assetItem->assetName = renamedAssetName;
+
+         //Whatever status we had prior is no longer relevent, so reset the status
+         resetAssetValidationStatus(assetItem);
+         importIssues = false;
+      }
+   }
+   else if (assetItem->statusType == String("MissingFile"))
+   {
+      //Trigger callback to look?
+   }
+}
+
+//
+// Importing
+//
+StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath)
+{
+   String assetType = getAssetTypeByFile(filePath);
+
+   if (assetType == String("Folder") || assetType == String("Zip"))
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is a folder or zip.", filePath.getFullPath().c_str());
+      activityLog.push_back(importLogBuffer);
+      return StringTable->EmptyString();
+   }
+
+   if (assetType.isEmpty())
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is of an unrecognized/unsupported type.", filePath.getFullPath().c_str());
+      activityLog.push_back(importLogBuffer);
+      return StringTable->EmptyString();
+   }
+
+   //Find out if the filepath has an associated module to it. If we're importing in-place, it needs to be within a module's directory
+   ModuleDefinition* targetModuleDef = getModuleFromPath(filePath);
+
+   if (targetModuleDef == nullptr)
+   {
+      //log it
+      return StringTable->EmptyString();
+   }
+   else
+   {
+      targetModuleId = targetModuleDef->getModuleId();
+   }
+
+   //set our path
+   targetPath = filePath.getPath();
+
+   //use a default import config
+   activeImportConfig = AssetImportConfig();
+
+   AssetImportObject* assetItem = addImportingAsset(assetType, filePath, nullptr, "");
+
+   importingAssets.push_back(assetItem);
+
+   processImportAssets();
+
+   bool hasIssues = validateAssets();
+
+   if (hasIssues)
+   {
+      //log it
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Import process has failed due to issues discovered during validation!");
+      activityLog.push_back(importLogBuffer);
+   }
+   else
+   {
+      importAssets();
+   }
+
+#if TORQUE_DEBUG
+   for (U32 i = 0; i < activityLog.size(); i++)
+   {
+      Con::printf(activityLog[i].c_str());
+   }
+#endif
+
+   if (hasIssues)
+   {
+      return StringTable->EmptyString();
+   }
+   else
+   {
+      String assetId = targetModuleId + ":" + assetItem->assetName;
+      return StringTable->insert(assetId.c_str());
+   }
+}
+
+void AssetImporter::importAssets(AssetImportObject* assetItem)
+{
+   ModuleDefinition* moduleDef = ModuleDatabase.findModule(targetModuleId.c_str(), 1);
+
+   if (moduleDef == nullptr)
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Unable to find moduleId %s", targetModuleId.c_str());
+      activityLog.push_back(importLogBuffer);
+      return;
+   }
+
+   if (assetItem == nullptr)
+   {
+      for (U32 i = 0; i < importingAssets.size(); i++)
+      {
+         if (importingAssets[i]->skip)
+            continue;
+
+         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"))
+            assetPath = SoundAsset::importAsset(importingAssets[i]);*/
+         else if (importingAssets[i]->assetType == String("MaterialAsset"))
+            assetPath = importMaterialAsset(importingAssets[i]);
+         /*else if (importingAssets[i]->assetType == String("ShapeAnimationAsset"))
+            assetPath = ShapeAnimationAsset::importAsset(importingAssets[i]);*/
+
+         if (assetPath.isEmpty())
+         {
+            dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Import attempt of %s failed, so skipping asset.", importingAssets[i]->assetName.c_str());
+            activityLog.push_back(importLogBuffer);
+
+            continue;
+         }
+
+         //If we got a valid filepath back from the import action, then we know we're good to go and we can go ahead and register the asset!
+         if (!isReimport)
+         {
+            bool registerSuccess = AssetDatabase.addDeclaredAsset(moduleDef, assetPath.getFullPath().c_str());
+
+            if (!registerSuccess)
+            {
+               dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to successfully register new asset at path %s to moduleId %s", assetPath.getFullPath().c_str(), targetModuleId.c_str());
+               activityLog.push_back(importLogBuffer);
+            }
+         }
+         else
+         {
+            String assetId = importingAssets[i]->moduleName + ":" + importingAssets[i]->assetName;
+            bool refreshSuccess = AssetDatabase.refreshAsset(assetId.c_str());
+
+            if (!refreshSuccess)
+            {
+               dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to refresh reimporting asset %s.", importingAssets[i]->assetName.c_str());
+               activityLog.push_back(importLogBuffer);
+            }
+         }
+
+         //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 = SoundAsset::importAsset(childItem);*/
+         else if (childItem->assetType == String("MaterialAsset"))
+            assetPath = importMaterialAsset(childItem);
+         /*else if (childItem->assetType == String("ShapeAnimationAsset"))
+            assetPath = ShapeAnimationAsset::importAsset(childItem);*/
+
+         if (assetPath.isEmpty())
+         {
+            dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Import attempt of %s failed, so skipping asset.", childItem->assetName.c_str());
+            activityLog.push_back(importLogBuffer);
+
+            continue;
+         }
+
+         //If we got a valid filepath back from the import action, then we know we're good to go and we can go ahead and register the asset!
+         if (!isReimport)
+         {
+            bool registerSuccess = AssetDatabase.addDeclaredAsset(moduleDef, assetPath.getFullPath().c_str());
+
+            if (!registerSuccess)
+            {
+               dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to successfully register new asset at path %s to moduleId %s", assetPath.getFullPath().c_str(), targetModuleId.c_str());
+               activityLog.push_back(importLogBuffer);
+            }
+         }
+         else
+         {
+            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);
+            }
+         }
+
+         //recurse if needed
+         importAssets(childItem);
+      }
+   }
+}
+
+//
+// Type-specific import logic
+//
+
+Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem)
+{
+   dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Image Asset: %s", assetItem->assetName.c_str());
+   activityLog.push_back(importLogBuffer);
+
+   ImageAsset* newAsset = new ImageAsset();
+   newAsset->registerObject();
+
+   StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str());
+
+   String imageFileName = assetItem->filePath.getFileName() + "." + assetItem->filePath.getExtension();
+   String assetPath = targetPath + "/" + imageFileName;
+   String tamlPath = targetPath + "/" + assetName + ".asset.taml";
+   String originalPath = assetItem->filePath.getFullPath().c_str();
+
+   char qualifiedFromFile[2048];
+   char qualifiedToFile[2048];
+
+   Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
+   Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
+   
+   newAsset->setAssetName(assetName);
+   newAsset->setImageFileName(imageFileName.c_str());
+   newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
+
+   ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(assetItem->imageSuffixType.c_str());
+   newAsset->setImageType(imageType);
+
+   Taml tamlWriter;
+   bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
+
+   if (!importSuccessful)
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str());
+      activityLog.push_back(importLogBuffer);
+      return "";
+   }
+
+   if (!isReimport)
+   {
+      bool isInPlace = !dStrcmp(qualifiedFromFile, qualifiedToFile);
+
+      if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport))
+      {
+         dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str());
+         activityLog.push_back(importLogBuffer);
+         return "";
+      }
+   }
+
+   return tamlPath;
+}
+
+Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
+{
+   dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Material Asset: %s", assetItem->assetName.c_str());
+   activityLog.push_back(importLogBuffer);
+
+   MaterialAsset* newAsset = new MaterialAsset();
+   newAsset->registerObject();
+
+   StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str());
+
+   String tamlPath = targetPath + "/" + assetName + ".asset.taml";
+   String scriptName = assetItem->assetName + ".cs";
+   String scriptPath = targetPath + "/" + scriptName;
+   String originalPath = assetItem->filePath.getFullPath().c_str();
+
+   char qualifiedFromFile[2048];
+
+   Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
+
+   newAsset->setAssetName(assetName);
+   newAsset->setScriptFile(scriptName.c_str());
+   newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
+
+   //iterate through and write out the material maps dependencies
+   S32 dependencySlotId = 0;
+   for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+   {
+      AssetImportObject* childItem = assetItem->childAssetItems[i];
+
+      if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
+         continue;
+
+      char dependencyFieldName[64];
+      dSprintf(dependencyFieldName, 64, "imageMap%i", dependencySlotId);
+
+      char dependencyFieldDef[512];
+      dSprintf(dependencyFieldDef, 512, "@Asset=%s:%s", targetModuleId.c_str(), childItem->assetName.c_str());
+
+      newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
+
+      dependencySlotId++;
+   }
+
+   Taml tamlWriter;
+   bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
+
+   if (!importSuccessful)
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str());
+      activityLog.push_back(importLogBuffer);
+      return "";
+   }
+
+   //build the PBRConfig file if we're flagged to and have valid image maps
+   if (activeImportConfig.CreatePBRConfig)
+   {
+      AssetImportObject* pbrConfigMap = nullptr;
+      AssetImportObject* roughnessMap = nullptr;
+      AssetImportObject* metalnessMap = nullptr;
+      AssetImportObject* aoMap = nullptr;
+
+      //We need to find any/all respective image maps for the given channels
+      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+      {
+         AssetImportObject* childItem = assetItem->childAssetItems[i];
+
+         if (childItem->skip || childItem->assetType.compare("ImageAsset") != 0)
+            continue;
+
+         if (childItem->imageSuffixType.compare("PBRConfig") == 0)
+            pbrConfigMap = childItem;
+         else if(childItem->imageSuffixType.compare("Roughness") == 0)
+            roughnessMap = childItem;
+         else if (childItem->imageSuffixType.compare("Metalness") == 0)
+            metalnessMap = childItem;
+         else if (childItem->imageSuffixType.compare("AO") == 0)
+            aoMap = childItem;
+      }
+
+      if (pbrConfigMap != nullptr && pbrConfigMap->generatedAsset)
+      {
+         if (roughnessMap != nullptr || metalnessMap != nullptr || aoMap != nullptr)
+         {
+            U32 channelKey[4] = { 0,1,2,3 };
+
+            GFX->getTextureManager()->saveCompositeTexture(aoMap->filePath.getFullPath(), roughnessMap->filePath.getFullPath(), metalnessMap->filePath.getFullPath(), "",
+               channelKey, pbrConfigMap->filePath.getFullPath(), &GFXTexturePersistentProfile);
+         }
+      }
+   }
+
+   FileObject* file = new FileObject();
+   file->registerObject();
+
+   //Now write the script file containing our material out
+   if (file->openForWrite(scriptPath.c_str()))
+   {
+      file->writeLine((U8*)"//--- OBJECT WRITE BEGIN ---");
+
+      char lineBuffer[1024];
+      dSprintf(lineBuffer, 1024, "singleton Material(%s) {", assetName);
+      file->writeLine((U8*)lineBuffer);
+
+      dSprintf(lineBuffer, 1024, "   mapTo=\"%s\";", assetName);
+      file->writeLine((U8*)lineBuffer);
+
+      for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+      {
+         AssetImportObject* childItem = assetItem->childAssetItems[i];
+
+         if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
+            continue;
+
+         String mapFieldName = "";
+
+         if (childItem->imageSuffixType.compare("Albedo") == 0)
+         {
+            mapFieldName = "DiffuseMap";
+         }
+
+         String path = childItem->filePath.getFullFileName();
+         dSprintf(lineBuffer, 1024, "   %s[0] = \"%s\";", mapFieldName.c_str(), path.c_str());
+         file->writeLine((U8*)lineBuffer);
+
+         dSprintf(lineBuffer, 1024, "   %sAsset[0] = \"%s:%s\";", mapFieldName.c_str(), targetModuleId.c_str(), childItem->assetName.c_str());
+         file->writeLine((U8*)lineBuffer);
+      }
+
+      file->writeLine((U8*)"};");
+      file->writeLine((U8*)"//--- OBJECT WRITE END ---");
+
+      file->close();
+   }
+   else
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset script file %s", scriptPath.c_str());
+      activityLog.push_back(importLogBuffer);
+      return "";
+   }
+
+   return tamlPath;
+}
+
+Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
+{
+   dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Shape Asset: %s", assetItem->assetName.c_str());
+   activityLog.push_back(importLogBuffer);
+
+   ShapeAsset* newAsset = new ShapeAsset();
+   newAsset->registerObject();
+
+   StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str());
+
+   String shapeFileName = assetItem->filePath.getFileName() + "." + assetItem->filePath.getExtension();
+   String assetPath = targetPath + "/" + shapeFileName;
+   String constructorPath = targetPath + "/" + assetItem->filePath.getFileName() + ".cs";
+   String tamlPath = targetPath + "/" + assetName + ".asset.taml";
+   String originalPath = assetItem->filePath.getFullPath().c_str();
+   String originalConstructorPath = assetItem->filePath.getPath() + assetItem->filePath.getFileName() + ".cs";
+
+   char qualifiedFromFile[2048];
+   char qualifiedToFile[2048];
+   char qualifiedFromCSFile[2048];
+   char qualifiedToCSFile[2048];
+
+   Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
+   Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
+
+   Platform::makeFullPathName(originalConstructorPath.c_str(), qualifiedFromCSFile, sizeof(qualifiedFromCSFile));
+   Platform::makeFullPathName(constructorPath.c_str(), qualifiedToCSFile, sizeof(qualifiedToCSFile));
+
+   newAsset->setAssetName(assetName);
+   newAsset->setShapeFile(shapeFileName.c_str());
+   newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
+
+   //iterate through and write out the material maps dependencies
+   S32 dependencySlotId = 0;
+   for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
+   {
+      AssetImportObject* childItem = assetItem->childAssetItems[i];
+
+      if (childItem->skip || !childItem->processed)
+         continue;
+
+      if (childItem->assetType.compare("MaterialAsset") == 0)
+      {
+         char dependencyFieldName[64];
+         dSprintf(dependencyFieldName, 64, "materialSlot%i", dependencySlotId);
+
+         char dependencyFieldDef[512];
+         dSprintf(dependencyFieldDef, 512, "@Asset=%s:%s", targetModuleId.c_str(), childItem->assetName.c_str());
+  
+         newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
+
+         dependencySlotId++;
+      }
+      else if (childItem->assetType.compare("ShapeAnimationAsset") == 0)
+      {
+         char dependencyFieldName[64];
+         dSprintf(dependencyFieldName, 64, "animationSequence%i", dependencySlotId);
+
+         char dependencyFieldDef[512];
+         dSprintf(dependencyFieldDef, 512, "@Asset=%s:%s", targetModuleId.c_str(), childItem->assetName.c_str());
+
+         newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
+
+         dependencySlotId++;
+      }
+   }
+
+   Taml tamlWriter;
+   bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
+
+   if (!importSuccessful)
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str());
+      activityLog.push_back(importLogBuffer);
+      return "";
+   }
+
+   bool makeNewConstructor = true;
+   if (!isReimport)
+   {
+      bool isInPlace = !dStrcmp(qualifiedFromFile, qualifiedToFile);
+
+      if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport))
+      {
+         dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromFile);
+         activityLog.push_back(importLogBuffer);
+         return "";
+      }
+
+      if (!isInPlace && Platform::isFile(qualifiedFromCSFile))
+      {
+         if(!dPathCopy(qualifiedFromCSFile, qualifiedToCSFile, !isReimport))
+         {
+            dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromCSFile);
+            activityLog.push_back(importLogBuffer);
+         }
+         else
+         {
+            //We successfully copied the original constructor file, so no extra work required
+            makeNewConstructor = false;
+            dSprintf(importLogBuffer, sizeof(importLogBuffer), "Successfully copied original TSShape Constructor file %s", qualifiedFromCSFile);
+            activityLog.push_back(importLogBuffer);
+         }
+      }
+   }
+
+   if (makeNewConstructor)
+   {
+      dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning creation of new TSShapeConstructor file: %s", qualifiedToCSFile);
+      activityLog.push_back(importLogBuffer);
+
+      //find/create shape constructor
+      TSShapeConstructor* constructor = TSShapeConstructor::findShapeConstructor(Torque::Path(qualifiedToFile).getFullPath());
+      if (constructor == nullptr)
+      {
+         constructor = new TSShapeConstructor(qualifiedToFile);
+
+         String constructorName = assetItem->filePath.getFileName() + "_" + assetItem->filePath.getExtension().substr(0, 3);
+         constructorName.replace("-", "_");
+         constructorName.replace(".", "_");
+         constructorName = Sim::getUniqueName(constructorName.c_str());
+         constructor->registerObject(constructorName.c_str());
+      }
+
+
+      //now we write the import config logic into the constructor itself to ensure we load like we wanted it to
+      String neverImportMats;
+
+      if (activeImportConfig.IgnoreMaterials.isNotEmpty())
+      {
+         U32 ignoredMatNamesCount = StringUnit::getUnitCount(activeImportConfig.IgnoreMaterials, ",;");
+         for (U32 i = 0; i < ignoredMatNamesCount; i++)
+         {
+            if (i == 0)
+               neverImportMats = StringUnit::getUnit(activeImportConfig.IgnoreMaterials, i, ",;");
+            else
+               neverImportMats += String("\t") + StringUnit::getUnit(activeImportConfig.IgnoreMaterials, i, ",;");
+         }
+      }
+
+      if (activeImportConfig.DoUpAxisOverride)
+      {
+         S32 upAxis;
+         if (activeImportConfig.UpAxisOverride.compare("X_AXIS") == 0)
+         {
+            upAxis = domUpAxisType::UPAXISTYPE_X_UP;
+         }
+         else if (activeImportConfig.UpAxisOverride.compare("Y_AXIS") == 0)
+         {
+            upAxis = domUpAxisType::UPAXISTYPE_Y_UP;
+         }
+         else if (activeImportConfig.UpAxisOverride.compare("Z_AXIS") == 0)
+         {
+            upAxis = domUpAxisType::UPAXISTYPE_Z_UP;
+         }
+         constructor->mOptions.upAxis = (domUpAxisType)upAxis;
+      }
+
+      if (activeImportConfig.DoScaleOverride)
+         constructor->mOptions.unit = activeImportConfig.ScaleOverride;
+      else
+         constructor->mOptions.unit = -1;
+
+      enum eAnimTimingType
+      {
+         FrameCount = 0,
+         Seconds = 1,
+         Milliseconds = 1000
+      };
+
+      S32 lodType;
+      if (activeImportConfig.LODType.compare("TrailingNumber") == 0)
+         lodType = ColladaUtils::ImportOptions::eLodType::TrailingNumber;
+      else if (activeImportConfig.LODType.compare("SingleSize") == 0)
+         lodType = ColladaUtils::ImportOptions::eLodType::SingleSize;
+      else if (activeImportConfig.LODType.compare("DetectDTS") == 0)
+         lodType = ColladaUtils::ImportOptions::eLodType::DetectDTS;
+      constructor->mOptions.lodType = (ColladaUtils::ImportOptions::eLodType)lodType;
+
+      constructor->mOptions.singleDetailSize = activeImportConfig.convertLeftHanded;
+      constructor->mOptions.alwaysImport = activeImportConfig.ImportedNodes;
+      constructor->mOptions.neverImport = activeImportConfig.IgnoreNodes;
+      constructor->mOptions.alwaysImportMesh = activeImportConfig.ImportMeshes;
+      constructor->mOptions.neverImportMesh = activeImportConfig.IgnoreMeshes;
+      constructor->mOptions.ignoreNodeScale = activeImportConfig.IgnoreNodeScale;
+      constructor->mOptions.adjustCenter = activeImportConfig.AdjustCenter;
+      constructor->mOptions.adjustFloor = activeImportConfig.AdjustFloor;
+
+      constructor->mOptions.convertLeftHanded = activeImportConfig.convertLeftHanded;
+      constructor->mOptions.calcTangentSpace = activeImportConfig.calcTangentSpace;
+      constructor->mOptions.genUVCoords = activeImportConfig.genUVCoords;
+      constructor->mOptions.flipUVCoords = activeImportConfig.flipUVCoords;
+      constructor->mOptions.findInstances = activeImportConfig.findInstances;
+      constructor->mOptions.limitBoneWeights = activeImportConfig.limitBoneWeights;
+      constructor->mOptions.joinIdenticalVerts = activeImportConfig.JoinIdenticalVerts;
+      constructor->mOptions.reverseWindingOrder = activeImportConfig.reverseWindingOrder;
+      constructor->mOptions.invertNormals = activeImportConfig.invertNormals;
+      constructor->mOptions.removeRedundantMats = activeImportConfig.removeRedundantMats;
+
+      S32 animTimingType;
+      if (activeImportConfig.animTiming.compare("FrameCount") == 0)
+         animTimingType = ColladaUtils::ImportOptions::eAnimTimingType::FrameCount;
+      else if (activeImportConfig.animTiming.compare("Seconds") == 0)
+         animTimingType = ColladaUtils::ImportOptions::eAnimTimingType::Seconds;
+      else// (activeImportConfig.animTiming.compare("Milliseconds") == 0)
+         animTimingType = ColladaUtils::ImportOptions::eAnimTimingType::Milliseconds;
+
+      constructor->mOptions.animTiming = (ColladaUtils::ImportOptions::eAnimTimingType)animTimingType;
+
+      constructor->mOptions.animFPS = activeImportConfig.animFPS;
+
+      constructor->mOptions.neverImportMat = neverImportMats;
+
+      if (!constructor->save(constructorPath.c_str()))
+      {
+         dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Failed to save shape constructor file to %s", constructorPath.c_str());
+         activityLog.push_back(importLogBuffer);
+      }
+      else
+      {
+         dSprintf(importLogBuffer, sizeof(importLogBuffer), "Finished creating shape constructor file to %s", constructorPath.c_str());
+         activityLog.push_back(importLogBuffer);
+      }
+   }
+
+   return tamlPath;
+}

+ 777 - 0
Engine/source/T3D/assets/assetImporter.h

@@ -0,0 +1,777 @@
+#pragma once
+
+#include "assets/assetPtr.h"
+#include "assets/assetManager.h"
+#include "module/moduleManager.h"
+#include "util/settings.h"
+#include "gui/controls/guiTreeViewCtrl.h"
+
+/// <summary>
+/// AssetImportConfig is a SimObject derived object intended to act as a container for all the necessary configuration data when running the Asset Importer.
+/// It dictates if and how any given asset type will be processed when running an import action. This is because the Asset Importer utilizes a lot of informed logic
+/// to try and automate as much of the import process as possible. In theory, you would run the import on a given file, and based on your config the importer will do
+/// everything from importing the designated file, as well as finding and importing any associated files such as images or materials, and prepping the objects at time
+/// of import to avoid as much manual post-processing as possible.
+/// </summary>
+class AssetImportConfig : public SimObject
+{
+   //General Settings
+public:
+   /// <summary>
+   /// Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename
+   /// </summary>
+   String DuplicatAutoResolution;
+
+   /// <summary>
+   /// Indicates if warnings should be treated as errors.
+   /// </summary>
+   bool WarningsAsErrors;
+
+   /// <summary>
+   /// Indicates if importing should be prevented from completing if any errors are detected at all
+   /// </summary>
+   bool PreventImportWithErrors;
+
+   /// <summary>
+   /// Should the importer automatically prompt to find missing files if they are not detected automatically by the importer
+   /// </summary>
+   bool AutomaticallyPromptMissingFiles;
+   //
+
+   //
+   //Mesh Settings
+   /// <summary>
+   /// Indicates if this config supports importing meshes
+   /// </summary>
+   bool ImportMesh;
+
+   /// <summary>
+   /// Indicates if the up axis in the model file should be overridden 
+   /// </summary>
+   bool DoUpAxisOverride;
+
+   /// <summary>
+   /// If overriding, what axis should be used as up. Options are X_AXIS, Y_AXIS, Z_AXIS
+   /// </summary>
+   String UpAxisOverride;
+
+   /// <summary>
+   /// Indicates if the scale in the model file should be overridden 
+   /// </summary>
+   bool DoScaleOverride;
+
+   /// <summary>
+   /// If overriding, what scale should be used
+   /// </summary>
+   F32 ScaleOverride;
+
+   /// <summary>
+   /// Indicates if scale of nodes should be ignored
+   /// </summary>
+   bool IgnoreNodeScale;
+
+   /// <summary>
+   /// Indicates if the center of the model file should be automatically recentered
+   /// </summary>
+   bool AdjustCenter;
+
+   /// <summary>
+   /// Indicates if the floor height of the model file should be automatically zero'd
+   /// </summary>
+   bool AdjustFloor;
+
+   /// <summary>
+   /// Indicates if submeshes should be collapsed down into a single main mesh
+   /// </summary>
+   bool CollapseSubmeshes;
+
+   /// <summary>
+   /// Indicates what LOD mode the model file should utilize to process out LODs. Options are TrailingNumber, DetectDTS, SingleSize
+   /// </summary>
+   String LODType;
+
+   //ImportAssetConfigSettingsList.addNewConfigSetting("TrailingNumber", "Trailing Number", "float", "", "2", "", "Mesh");
+   /// <summary>
+   /// A list of what nodes should be guaranteed to be imported if found in the model file. Separated by either , or ;
+   /// </summary>
+   String ImportedNodes;
+
+   /// <summary>
+   /// A list of what nodes should be guaranteed to not be imported if found in the model file. Separated by either , or ;
+   /// </summary>
+   String IgnoreNodes;
+
+   /// <summary>
+   /// A list of what mesh objects should be guaranteed to be imported if found in the model file. Separated by either , or ;
+   /// </summary>
+   String ImportMeshes;
+
+   /// <summary>
+   /// A list of what mesh objects should be guaranteed to not be imported if found in the model file. Separated by either , or ;
+   /// </summary>
+   String IgnoreMeshes;
+
+   //Assimp/Collada params
+   /// <summary>
+   /// Flag to indicate the shape loader should convert to a left-handed coordinate system
+   /// </summary>
+   bool convertLeftHanded;
+
+   /// <summary>
+   /// Should the shape loader calculate tangent space values
+   /// </summary>
+   bool calcTangentSpace;
+
+   /// <summary>
+   /// Should the shape loader automatically prune redundant/duplicate materials
+   /// </summary>
+   bool removeRedundantMats;
+
+   /// <summary>
+   /// Should the shape loader auto-generate UV Coordinates for the mesh.
+   /// </summary>
+   bool genUVCoords;
+
+   /// <summary>
+   /// Should the UV coordinates be transformed.
+   /// </summary>
+   bool TransformUVs;
+
+   /// <summary>
+   /// Should the UV coordinates be flipped
+   /// </summary>
+   bool flipUVCoords;
+
+   /// <summary>
+   /// Should the shape loader automatically look for instanced submeshes in the model file
+   /// </summary>
+   bool findInstances;
+
+   /// <summary>
+   /// Should the shape loader limit the bone weights
+   /// </summary>
+   bool limitBoneWeights;
+
+   /// <summary>
+   /// Should the shape loader automatically merge identical/duplicate verts
+   /// </summary>
+   bool JoinIdenticalVerts;
+
+   /// <summary>
+   /// Should the shape loader reverse the winding order of the mesh's face indicies
+   /// </summary>
+   bool reverseWindingOrder;
+
+   /// <summary>
+   /// Should the normals on the model be inverted
+   /// </summary>
+   bool invertNormals;
+   //
+
+   //
+   //Materials
+   /// <summary>
+   /// Does this config allow for importing of materials
+   /// </summary>
+   bool ImportMaterials;
+
+   /// <summary>
+   /// When importing a material, should it automatically attempt to merge Roughness, AO and Metalness maps into a single, composited PBR Configuration map
+   /// </summary>
+   bool CreatePBRConfig;
+
+   /// <summary>
+   /// When generating a material off of an importing image, should the importer force appending a diffusemap suffix onto the end to avoid potential naming confusion.
+   /// e.g. MyCoolStuff.png is imported, generating MyCoolStuff material asset and MyCoolStuff_Diffuse image asset
+   /// </summary>
+   bool UseDiffuseSuffixOnOriginImage;
+
+   /// <summary>
+   /// Should the importer try and use existing material assets in the game directory if at all possible. (Not currently utilized)
+   /// </summary>
+   bool UseExistingMaterials;
+
+   /// <summary>
+   /// A list of material names that should not be imported. Separated by either , or ;
+   /// </summary>
+   String IgnoreMaterials;
+
+   /// <summary>
+   /// When processing a material asset, should the importer attempt to populate the various material maps on it by looking up common naming conventions for potentially relevent image files
+   /// e.g. If MyCoolStuff_Diffuse.png is imported, generating MyCoolStuff material, it would also find MyCoolStuff_Normal and MyCoolStuff_PBR images and map them to the normal and PBRConfig maps respectively automatically
+   /// </summary>
+   bool PopulateMaterialMaps;
+
+   //
+   //Animations
+   /// <summary>
+   /// Does this config allow for importing Shape Animations
+   /// </summary>
+   bool ImportAnimations;
+
+   /// <summary>
+   /// When importing a shape file, should the animations within be separated out into unique files
+   /// </summary>
+   bool SeparateAnimations;
+
+   /// <summary>
+   /// If separating animations out from a source file, what prefix should be added to the names for grouping association
+   /// </summary>
+   String SeparateAnimationPrefix;
+
+   /// <summary>
+   /// Defines the animation timing for the given animation sequence. Options are FrameTime, Seconds, Milliseconds
+   /// </summary>
+   String animTiming;
+
+   /// <summary>
+   /// The FPS of the animation sequence
+   /// </summary>
+   F32 animFPS;
+
+   //
+   //Collision
+   /// <summary>
+   /// Does this configuration generate collision geometry when importing. (Not currently enabled)
+   /// </summary>
+   bool GenerateCollisions;
+
+   /// <summary>
+   /// What sort of collision geometry is generated. (Not currently enabled)
+   /// </summary>
+   String GenCollisionType;
+
+   /// <summary>
+   /// What prefix is added to the collision geometry generated. (Not currently enabled)
+   /// </summary>
+   String CollisionMeshPrefix;
+
+   /// <summary>
+   /// Does this configuration generate Line of Sight collision geometry. (Not currently enabled)
+   /// </summary>
+   bool  GenerateLOSCollisions;
+
+   /// <summary>
+   /// What sort of Line of Sight collision geometry is generated. (Not currently enabled)
+   /// </summary>
+   String GenLOSCollisionType;
+
+   /// <summary>
+   /// What prefix is added to the Line of Sight collision geometry generated. (Not currently enabled)
+   /// </summary>
+   String LOSCollisionMeshPrefix;
+
+   //
+   //Images
+   /// <summary>
+   /// Does this configuration support importing images.
+   /// </summary>
+   bool importImages;
+
+   /// <summary>
+   /// What is the default ImageType images are imported as. Options are: N/A, Diffuse, Normal, Metalness, Roughness, AO, PBRConfig, GUI, Cubemap
+   /// </summary>
+   String ImageType;
+
+   /// <summary>
+   /// What type of suffixes are scanned to detect if an importing image is a diffuse map.
+   /// e.g. _Albedo or _Color
+   /// </summary>
+   String DiffuseTypeSuffixes;
+
+   /// <summary>
+   /// What type of suffixes are scanned to detect if an importing image is a normal map.
+   /// e.g. _Normal or _Norm
+   /// </summary>
+   String NormalTypeSuffixes;
+
+   /// <summary>
+   /// What type of suffixes are scanned to detect if an importing image is a metalness map.
+   /// e.g. _Metalness or _Metal
+   /// </summary>
+   String MetalnessTypeSuffixes;
+
+   /// <summary>
+   /// What type of suffixes are scanned to detect if an importing image is a roughness map.
+   /// e.g. _roughness or _rough
+   /// </summary>
+   String RoughnessTypeSuffixes;
+
+   /// <summary>
+   /// What type of suffixes are scanned to detect if an importing image is a smoothness map.
+   /// e.g. _smoothness or _smooth
+   /// </summary>
+   String SmoothnessTypeSuffixes;
+
+   /// <summary>
+   /// What type of suffixes are scanned to detect if an importing image is a ambient occlusion map.
+   /// e.g. _ambient or _ao
+   /// </summary>
+   String AOTypeSuffixes;
+
+   /// <summary>
+   /// What type of suffixes are scanned to detect if an importing image is a PBRConfig map.
+   /// e.g. _Composite or _PBR
+   /// </summary>
+   String PBRTypeSuffixes;
+
+   /// <summary>
+   /// Indicates what filter mode images imported with this configuration utilizes. Options are Linear, Bilinear, Trilinear
+   /// </summary>
+   String TextureFilteringMode;
+
+   /// <summary>
+   /// Indicates if images imported with this configuration utilize mipmaps
+   /// </summary>
+   bool UseMips;
+
+   /// <summary>
+   /// Indicates if images imported with this configuration are in an HDR format
+   /// </summary>
+   bool IsHDR;
+
+   /// <summary>
+   /// Indicates what amount of scaling images imported with this configuration use
+   /// </summary>
+   F32 Scaling;
+
+   /// <summary>
+   /// Indicates if images imported with this configuration are compressed
+   /// </summary>
+   bool ImagesCompressed;
+
+   /// <summary>
+   /// Indicates if images imported with this configuration generate a parent material for it as well
+   /// </summary>
+   bool GenerateMaterialOnImport;
+
+   //
+   //Sounds
+   /// <summary>
+   /// Indicates if sounds are imported with this configuration
+   /// </summary>
+   bool importSounds;
+
+   /// <summary>
+   /// Indicates what amount the volume is adjusted on sounds imported with this configuration
+   /// </summary>
+   F32 VolumeAdjust;
+
+   /// <summary>
+   /// Indicates what amount the pitch is adjusted on sounds imported with this configuration
+   /// </summary>
+   F32 PitchAdjust;
+
+   /// <summary>
+   /// Indicates if sounds imported with this configuration are compressed
+   /// </summary>
+   bool SoundsCompressed;
+
+public:
+   AssetImportConfig();
+   virtual ~AssetImportConfig();
+
+   /// Engine.
+   static void initPersistFields();
+
+   /// <summary>
+   /// Loads a configuration from a Settings object
+   /// @param configSettings, The Settings object to load from
+   /// @param configName, The name of the configuration setting to load from the setting object
+   /// </summary>
+   void loadImportConfig(Settings* configSettings, String configName);
+
+   /// Declare Console Object.
+   DECLARE_CONOBJECT(AssetImportConfig);
+};
+
+/// <summary>
+/// AssetImportConfig is a SimObject derived object that represents and holds information for an importing asset. They are generated and processed by the AssetImporter
+/// </summary>
+class AssetImportObject : public SimObject
+{
+   typedef SimObject Parent;
+
+public:
+   /// <summary>
+   /// What type is the importing asset
+   /// </summary>
+   String assetType;
+
+   /// <summary>
+   /// What is the source file path of the importing asset
+   /// </summary>
+   Torque::Path filePath;
+
+   /// <summary>
+   /// What is the asset's name
+   /// </summary>
+   String assetName;
+
+   /// <summary>
+   /// What is the original, unmodified by processing, asset name
+   /// </summary>
+   String cleanAssetName;
+
+   /// <summary>
+   /// What is the name of the module this asset will be importing into
+   /// </summary>
+   String moduleName;
+
+   /// <summary>
+   /// What is the current status of this asset item in it's import process
+   /// </summary>
+   String status;
+
+   /// <summary>
+   /// If there is a warning or error status, what type is the condition for this asset item
+   /// </summary>
+   String statusType;
+
+   /// <summary>
+   /// What is the articulated information of the status of the asset. Contains the error or warning log data.
+   /// </summary>
+   String statusInfo;
+
+   /// <summary>
+   /// Is the asset item currently flagged as dirty
+   /// </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;
+
+   /// <summary>
+   /// Has the asset item been processed
+   /// </summary>
+   bool processed;
+
+   /// <summary>
+   /// Is this specific asset item generated as part of the import process of another item
+   /// </summary>
+   bool generatedAsset;
+
+   /// <summary>
+   /// What, if any, importing asset item is this item's parent
+   /// </summary>
+   AssetImportObject* parentAssetItem;
+
+   /// <summary>
+   /// What, if any, importing asset item are children of this item
+   /// </summary>
+   Vector< AssetImportObject*> childAssetItems;
+
+   /// <summary>
+   /// What is the ultimate asset taml file path for this import item
+   /// </summary>
+   String tamlFilePath;
+
+   //
+   /// <summary>
+   /// Specific to ImageAsset type
+   /// What is the image asset's suffix type. Options are: Albedo, Normal, Roughness, AO, Metalness, PBRConfig
+   /// </summary>
+   String imageSuffixType;
+
+   //
+   /// <summary>
+   /// Specific to ShapeAsset type
+   /// Processed information about the shape file. Contains numbers and lists of meshes, materials and animations
+   /// </summary>
+   GuiTreeViewCtrl* shapeInfo;
+
+public:
+   AssetImportObject();
+   virtual ~AssetImportObject();
+
+   /// Engine.
+   static void initPersistFields();
+
+   /// Declare Console Object.
+   DECLARE_CONOBJECT(AssetImportObject);
+};
+
+/// <summary>
+/// AssetImporter is a SimObject derived object that processed and imports files and turns them into assets if they are of valid types.
+/// Utilizes an AssetImportConfig to inform the importing process's behavior.
+/// </summary>
+class AssetImporter : public SimObject
+{
+   typedef SimObject Parent;
+
+   /// <summary>
+   /// The import configuration that is currently being utilized
+   /// </summary>
+   AssetImportConfig activeImportConfig;
+
+   /// <summary>
+   /// A log of all the actions that have been performed by the importer
+   /// </summary>
+   Vector<String> activityLog;
+
+   /// <summary>
+   /// A list of AssetImportObjects that are to be imported
+   /// </summary>
+   Vector<AssetImportObject*> importingAssets;
+
+   /// <summary>
+   /// A list of file paths that are to be imported. These are only used for resetting purposes;
+   /// </summary>
+   Vector<Torque::Path> originalImportingFiles;
+
+   /// <summary>
+   /// The Id of the module the assets are to be imported into
+   /// </summary>
+   String targetModuleId;
+
+   /// <summary>
+   /// The path any imported assets are placed in as their destination
+   /// </summary>
+   String targetPath;
+
+   /// <summary>
+   /// Are there any issues with any of the current import asset items
+   /// </summary>
+   bool importIssues;
+
+   /// <summary>
+   /// Is this import action a reimport of an existing asset
+   /// </summary>
+   bool isReimport;
+
+   /// <summary>
+   /// Has the heirarchy of asset import items changed due to processing
+   /// </summary>
+   bool assetHeirarchyChanged;
+
+   /// <summary>
+   /// A string used for writing into the importLog
+   /// </summary>
+   char importLogBuffer[1024];
+
+public:
+   AssetImporter();
+   virtual ~AssetImporter();
+
+   /// Engine.
+   static void initPersistFields();
+
+   /// Declare Console Object.
+   DECLARE_CONOBJECT(AssetImporter);
+
+   /// <summary>
+   /// Sets the target path for the assets being imported to be deposited into
+   /// <para>@param pTargetPath, The filePath of the destination point assets are imported into</para>
+   /// </summary>
+   void setTargetPath(Torque::Path pTargetPath) { targetPath = pTargetPath; }
+
+   /// <summary>
+   /// Processes a file into an AssetImportObject and adds it to the session for importing
+   /// <para>@param filePath, The filePath of the file to be imported in as an asset</para>
+   /// <para>@return AssetImportObject that was created</para>
+   /// </summary>
+   AssetImportObject* addImportingFile(Torque::Path filePath);
+
+   /// <summary>
+   /// Adds an importing asset to the current session
+   /// <para>@param assetType, Type of the asset being imported</para>
+   /// <para>@param filePath, path of the file to be imported</para>
+   /// <para>@param parentItem, AssetImportObject that the new item is a child of. null if no parent</para>
+   /// <para>@param assetNameOverride, If not blank, will be the new item's assetName instead of being created off of the filePath</para>
+   /// <para>@return AssetImportObject that was created</para>
+   /// </summary>
+   AssetImportObject* addImportingAsset(String assetType, Torque::Path filePath, AssetImportObject* parentItem, String assetNameOverride);
+
+   /// <summary>
+   /// Deletes the asset item from the import session. Affects the item's children as well
+   /// <para>@param assetItem, asset item to be marked as deleted</para>
+   /// </summary>
+   void deleteImportingAsset(AssetImportObject* assetItem);
+
+   /// <summary>
+   /// Finds an asset item in the session if it exists, by name
+   /// <para>@param assetName, Asset name to find</para>
+   /// <para>@param assetItem, if null, will loop over and recurse the main import asset items, if a specific AssetImportObject is passed in, it will recurse it's children</para>
+   /// <para>@return AssetImportObject that was found</para>
+   /// </summary>
+   AssetImportObject* findImportingAssetByName(String assetName, AssetImportObject* assetItem = nullptr);
+
+   /// <summary>
+   /// Finds the module associated with a given file path
+   /// <para>@param filePath, File path to parse the the module from</para>
+   /// <para>@return ModuleDefinition that was found</para>
+   /// </summary>
+   ModuleDefinition* getModuleFromPath(Torque::Path filePath);
+
+   /// <summary>
+   /// Parses an asset's name to try and find if any of the import config's suffix lists match to it
+   /// <para>@param assetName, Asset name to parse any image suffix out of</para>
+   /// <para>@param suffixType, output, The suffix type that was matched to the asset name</para>
+   /// <para>@return suffix that matched to the asset name</para>
+   /// </summary>
+   String parseImageSuffixes(String assetName, String* suffixType);
+
+   /// <summary>
+   /// Parses a file path to determine its asset type
+   /// <para>@param filePath, File path to parse</para>
+   /// <para>@return The asset type as a string</para>
+   /// </summary>
+   String getAssetTypeByFile(Torque::Path filePath);
+
+   /// <summary>
+   /// Resets the import session to a clean slate. This will clear all existing AssetImportObjects and the activity log
+   /// and then re-process the original filePaths again.
+   /// </summary>
+   void resetImportSession();
+
+   /// <summary>
+   /// Get the number of lines in the activity log
+   /// <para>@return Line count as S32</para>
+   /// </summary>
+   S32 getActivityLogLineCount();
+
+   /// <summary>
+   /// Gets the log line at a given index
+   /// <para>@param line, line in the log to get</para>
+   /// <para>@return The log line as a string</para>
+   /// </summary>
+   String getActivityLogLine(U32 line);
+
+   /// <summary>
+   /// Dumps the entire current activity log to the console.
+   /// </summary>
+   void dumpActivityLog();
+
+   /// <summary>
+   /// Gets the number of top-level asset items in the current import session(doesn't count children)
+   /// <para>@return Number of children</para>
+   /// </summary>
+   S32 getAssetItemCount();
+
+   /// <summary>
+   /// Get the top-level asset item in the current import session at the requested index
+   /// <para>@param index, The index of the item array to get</para>
+   /// <para>@return The AssetImportObject at the index</para>
+   /// </summary>
+   AssetImportObject* getAssetItem(U32 index);
+
+   /// <summary>
+   /// Gets the number of child asset items of a given AssetImportObject
+   /// <para>@param assetItem, The AssetImportObject to get the number of child items for</para>
+   /// <para>@return Number of children</para>
+   /// </summary>
+   S32 getAssetItemChildCount(AssetImportObject* assetItem);
+
+   /// <summary>
+   /// Get the child asset item of a specific AssetImportObject at the requested index
+   /// <para>@param assetItem, The AssetImportObject to get the number of child items for</para>
+   /// <para>@param index, The index of the child item array to get</para>
+   /// <para>@return The AssetImportObject at the index</para>
+   /// </summary>
+   AssetImportObject* getAssetItemChild(AssetImportObject* assetItem, U32 index);
+
+   /// <summary>
+   /// Process AssetImportObject's to prepare them for importing.
+   /// <para>@param assetItem, If null, will loop over the top-level asset items list, if a specific item is provided, will process it's children</para>
+   /// </summary>
+   void processImportAssets(AssetImportObject* assetItem = nullptr);
+
+   /// <summary>
+   /// Process a specific AssetImportObject that is an ImageAsset type to prepare it for importing
+   /// <para>@param assetItem, The AssetImportObject to process</para>
+   /// </summary>
+   void processImageAsset(AssetImportObject* assetItem);
+
+   /// <summary>
+   /// Process a specific AssetImportObject that is an MaterialAsset type to prepare it for importing
+   /// <para>@param assetItem, The AssetImportObject to process</para>
+   /// </summary>
+   void processMaterialAsset(AssetImportObject* assetItem);
+
+   /// <summary>
+   /// Process a specific AssetImportObject that is an ShapeAsset type to prepare it for importing
+   /// <para>@param assetItem, The AssetImportObject to process</para>
+   /// </summary>
+   void processShapeAsset(AssetImportObject* assetItem);
+
+   /// <summary>
+   /// Process a specific ShapeAsset AssetImportObject with a material id in order to parse and handle the materials listed in the shape file
+   /// <para>@param assetItem, The AssetImportObject to process</para>
+   /// <para>@param materialItemId, The materialItemId in the shapeInfo to process</para>
+   /// </summary>
+   void processShapeMaterialInfo(AssetImportObject* assetItem, S32 materialItemId);
+
+   /// <summary>
+   /// Run through and validate assets for issues, such as name collisions
+   /// </summary>
+   bool validateAssets();
+
+   /// <summary>
+   /// Validate a specific asset item
+   /// <para>@param assetItem, The AssetImportObject to validate</para>
+   /// </summary>
+   void validateAsset(AssetImportObject* assetItem);
+
+   /// <summary>
+   /// Reset the validation status of asset items
+   /// <para>@param assetItem, If null, will loop over the top-level asset items list, if a specific item is provided, will reset it's children</para>
+   /// </summary>
+   void resetAssetValidationStatus(AssetImportObject* assetItem = nullptr);
+
+   /// <summary>
+   /// Checks asset items for any collisions in the current import session
+   /// <para>@param assetItemToCheckFor, The asset to check for collisions with</para>
+   /// <para>@param assetItem, if null, will loop over and recurse the main import asset items, if a specific AssetImportObject is passed in, it will recurse it's children</para>
+   /// <para>@return If a collision was detected</para>
+   /// </summary>
+   bool checkAssetForCollision(AssetImportObject* assetItemToCheckFor, AssetImportObject* assetItem = nullptr);
+
+   /// <summary>
+   /// Attempts to automatically resolve import issues according to the import config settings
+   /// <para>@param assetItem, The AssetImportObject to resolve</para>
+   /// </summary>
+   void resolveAssetItemIssues(AssetImportObject* assetItem);
+
+   /// <summary>
+   /// Runs the import process on a single file in-place. Intended primarily for autoimporting a loose file that's in the game directory.
+   /// <para>@param filePath, The filePath of the file to be imported in as an asset</para>
+   /// <para>@return AssetId of the asset that was imported. If import failed, it will be empty.</para>
+   /// </summary>
+   StringTableEntry autoImportFile(Torque::Path filePath);
+
+   /// <summary>
+   /// Runs the import process in the current session
+   /// <para>@param assetItem, if null, will loop over and recurse the main import asset items, if a specific AssetImportObject is passed in, it will recurse it's children</para>
+   /// </summary>
+   void importAssets(AssetImportObject* assetItem = nullptr);
+
+   /// <summary>
+   /// Runs the import processing on a specific ImageAsset item
+   /// <para>@param assetItem, The asset item to import</para>
+   /// <para>@return AssetId of the asset that was imported. If import failed, it will be empty.</para>
+   /// </summary>
+   Torque::Path importImageAsset(AssetImportObject* assetItem);
+
+   /// <summary>
+   /// Runs the import processing on a specific MaterialAsset item
+   /// <para>@param assetItem, The asset item to import</para>
+   /// <para>@return AssetId of the asset that was imported. If import failed, it will be empty.</para>
+   /// </summary>
+   Torque::Path importMaterialAsset(AssetImportObject* assetItem);
+
+   /// <summary>
+   /// Runs the import processing on a specific ShapeAsset item
+   /// <para>@param assetItem, The asset item to import</para>
+   /// <para>@return AssetId of the asset that was imported. If import failed, it will be empty.</para>
+   /// </summary>
+   Torque::Path importShapeAsset(AssetImportObject* assetItem);   
+
+   //
+   /// <summary>
+   /// Gets the currently active import configuration
+   /// <para>@return Current AssetImportConfig the importer is using</para>
+   /// </summary>
+   AssetImportConfig* getImportConfig() { return &activeImportConfig; }
+};

+ 140 - 0
Engine/source/T3D/assets/assetImporter_ScriptBinding.h

@@ -0,0 +1,140 @@
+#pragma once
+
+#include "console/engineAPI.h"
+#include "assetImporter.h"
+
+//Console Functions
+
+DefineEngineMethod(AssetImportConfig, loadImportConfig, void, (Settings* configSettings, String configName), (nullAsType<Settings*>(), ""),
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->loadImportConfig(configSettings, configName);
+}
+
+DefineEngineMethod(AssetImporter, setTargetPath, void, (String path), (""),
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->setTargetPath(path);
+}
+
+DefineEngineMethod(AssetImporter, resetImportSession, void, (), ,
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->resetImportSession();
+}
+
+DefineEngineMethod(AssetImporter, dumpActivityLog, void, (), ,
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->dumpActivityLog();
+}
+
+DefineEngineMethod(AssetImporter, getActivityLogLineCount, S32, (),,
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->getActivityLogLineCount();
+}
+
+DefineEngineMethod(AssetImporter, getActivityLogLine, String, (S32 i), (0),
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->getActivityLogLine(0);
+}
+
+DefineEngineMethod(AssetImporter, autoImportFile, String, (String path), (""),
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->autoImportFile(path);
+}
+
+DefineEngineMethod(AssetImporter, addImportingFile, AssetImportObject*, (String path), (""),
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->addImportingFile(path);
+}
+
+DefineEngineMethod(AssetImporter, processImportingAssets, void, (), ,
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->processImportAssets();
+}
+
+DefineEngineMethod(AssetImporter, validateImportingAssets, bool, (), ,
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->validateAssets();
+}
+
+DefineEngineMethod(AssetImporter, resolveAssetItemIssues, void, (AssetImportObject* assetItem), (nullAsType< AssetImportObject*>()),
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   object->resolveAssetItemIssues(assetItem);
+}
+
+DefineEngineMethod(AssetImporter, importAssets, void, (),,
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->importAssets();
+}
+
+DefineEngineMethod(AssetImporter, getAssetItemCount, S32, (),,
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->getAssetItemCount();
+}
+
+DefineEngineMethod(AssetImporter, getAssetItem, AssetImportObject*, (S32 index), (0),
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   return object->getAssetItem(index);
+}
+
+DefineEngineMethod(AssetImporter, getAssetItemChildCount, S32, (AssetImportObject* assetItem), (nullAsType< AssetImportObject*>()),
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   if (assetItem == nullptr)
+      return 0;
+
+   return object->getAssetItemChildCount(assetItem);
+}
+
+DefineEngineMethod(AssetImporter, getAssetItemChild, AssetImportObject*, (AssetImportObject* assetItem, S32 index), (nullAsType< AssetImportObject*>(), 0),
+   "Creates a new script asset using the targetFilePath.\n"
+   "@return The bool result of calling exec")
+{
+   if (assetItem == nullptr)
+      return nullptr;
+
+   return object->getAssetItemChild(assetItem, index);
+}
+
+
+/*DefineEngineFunction(enumColladaForImport, bool, (const char* shapePath, const char* ctrl, bool loadCachedDts), ("", "", true),
+   "(string shapePath, GuiTreeViewCtrl ctrl) Collect scene information from "
+   "a COLLADA file and store it in a GuiTreeView control. This function is "
+   "used by the COLLADA import gui to show a preview of the scene contents "
+   "prior to import, and is probably not much use for anything else.\n"
+   "@param shapePath COLLADA filename\n"
+   "@param ctrl GuiTreeView control to add elements to\n"
+   "@param loadCachedDts dictates if it should try and load the cached dts file if it exists"
+   "@return true if successful, false otherwise\n"
+   "@ingroup Editors\n"
+   "@internal")
+{
+   return enumColladaForImport(shapePath, ctrl, loadCachedDts);
+}*/

+ 3 - 0
Engine/source/T3D/cameraSpline.cpp

@@ -36,6 +36,7 @@ CameraSpline::Knot::Knot()
    mSpeed = 0.0f;
    mType = NORMAL;
    mPath = SPLINE;
+   mDistance = 0.0f;
    prev = NULL; next = NULL;
 };
 
@@ -46,6 +47,7 @@ CameraSpline::Knot::Knot(const Knot &k)
    mSpeed    = k.mSpeed;
    mType = k.mType;
    mPath = k.mPath;
+   mDistance = k.mDistance;
    prev = NULL; next = NULL;
 }
 
@@ -56,6 +58,7 @@ CameraSpline::Knot::Knot(const Point3F &p, const QuatF &r, F32 s, Knot::Type typ
    mSpeed    = s;
    mType = type;
    mPath = path;
+   mDistance = 0.0f;
    prev = NULL; next = NULL;
 }
 

+ 2 - 2
Engine/source/T3D/convexShape.cpp

@@ -92,12 +92,12 @@ void ConvexShapeCollisionConvex::getFeatures( const MatrixF &mat, const VectorF
 	if ( pShape->mGeometry.points.empty() )
 	{
 		cf->material = 0;
-		cf->object = NULL;
+		cf->mObject = NULL;
 		return;
 	}
 
 	cf->material = 0;
-	cf->object = mObject;
+	cf->mObject = mObject;
 
 	// Simple implementation... Add all Points, Edges and Faces.
 

+ 2 - 2
Engine/source/T3D/convexShape.h

@@ -50,7 +50,7 @@ protected:
 
 public:
 
-	ConvexShapeCollisionConvex() { mType = ConvexShapeCollisionConvexType; }
+   ConvexShapeCollisionConvex() { pShape = NULL; mType = ConvexShapeCollisionConvexType; }
 
 	ConvexShapeCollisionConvex( const ConvexShapeCollisionConvex& cv ) {
 		mType      = ConvexShapeCollisionConvexType;
@@ -297,4 +297,4 @@ protected:
 
 };
 
-#endif // _CONVEXSHAPE_H_
+#endif // _CONVEXSHAPE_H_

+ 2 - 0
Engine/source/T3D/debris.cpp

@@ -533,6 +533,8 @@ Debris::Debris()
    mInitialTrans.identity();
    mRadius = 0.2f;
    mStatic = false;
+   mElasticity = 0.5f;
+   mFriction = 0.5f;
 
    dMemset( mEmitterList, 0, sizeof( mEmitterList ) );
 

+ 17 - 0
Engine/source/T3D/decal/decalInstance.cpp

@@ -24,6 +24,23 @@
 #include "T3D/decal/decalInstance.h"
 #include "scene/sceneRenderState.h"
 
+DecalInstance::DecalInstance()
+   : mDataBlock(NULL),
+   mRotAroundNormal(0.0f),
+   mSize(0.0f),
+   mCreateTime(0),
+   mVisibility(1.0f),
+   mLastAlpha(1.0f),
+   mTextureRectIdx(0),
+   mVerts(NULL),
+   mIndices(NULL),
+   mVertCount(0),
+   mIndxCount(0),
+   mFlags(0),
+   mRenderPriority(0),
+   mId(-1),
+   mCustomTex(NULL)
+{}
 void DecalInstance::getWorldMatrix( MatrixF *outMat, bool flip )
 {
    outMat->setPosition( mPosition );

+ 1 - 1
Engine/source/T3D/decal/decalInstance.h

@@ -87,7 +87,7 @@ class DecalInstance
       /// Calculates the size of this decal onscreen in pixels, used for LOD.
       F32 calcPixelSize( U32 viewportHeight, const Point3F &cameraPos, F32 worldToScreenScaleY ) const;
    		
-	   DecalInstance() : mId(-1) {}   
+      DecalInstance();
 };
 
 #endif // _DECALINSTANCE_H_

+ 5 - 1
Engine/source/T3D/fx/explosion.cpp

@@ -238,6 +238,9 @@ ExplosionData::ExplosionData()
    explosionScale.set(1.0f, 1.0f, 1.0f);
    playSpeed = 1.0f;
 
+   explosionShape = NULL;
+   explosionAnimation = -1;
+
    dMemset( emitterList, 0, sizeof( emitterList ) );
    dMemset( emitterIDList, 0, sizeof( emitterIDList ) );
    dMemset( debrisList, 0, sizeof( debrisList ) );
@@ -924,6 +927,7 @@ Explosion::Explosion()
    ss_index = 0;
    mDataBlock = 0;
    soundProfile_clone = 0;
+   mRandomVal = 0;
 }
 
 Explosion::~Explosion()
@@ -962,7 +966,7 @@ void Explosion::setInitialState(const Point3F& point, const Point3F& normal, con
 void Explosion::initPersistFields()
 {
    Parent::initPersistFields();
-
+   addField("initialNormal", TypePoint3F, Offset(mInitialNormal, Explosion), "Initial starting Normal.");
    //
 }
 

+ 11 - 1
Engine/source/T3D/fx/fxFoliageReplicator.cpp

@@ -286,6 +286,7 @@ fxFoliageReplicator::fxFoliageReplicator()
    // Reset Foliage Count.
    mCurrentFoliageCount = 0;
 
+   dMemset(&mFrustumRenderSet, 0, sizeof(mFrustumRenderSet));
    // Reset Creation Area Angle Animation.
    mCreationAreaAngle = 0;
 
@@ -299,8 +300,15 @@ fxFoliageReplicator::fxFoliageReplicator()
 
    // Reset Frame Serial ID.
    mFrameSerialID = 0;
-
+   mQuadTreeLevels = 0;
+   mNextAllocatedNodeIdx = 0;
    mAlphaLookup = NULL;
+   mFadeInGradient = 0.0f;
+   mFadeOutGradient = 0.0f;
+   mGlobalSwayPhase = 0.0f;
+   mGlobalSwayTimeRatio = 1.0f;
+   mGlobalLightPhase = 0.0f;
+   mGlobalLightTimeRatio = 1.0f;
 
    mDirty = true;
 
@@ -317,6 +325,8 @@ fxFoliageReplicator::fxFoliageReplicator()
    mFoliageShaderTrueBillboardSC = NULL;
    mFoliageShaderGroundAlphaSC = NULL;
    mFoliageShaderAmbientColorSC = NULL;
+   mDiffuseTextureSC = NULL;
+   mAlphaMapTextureSC = NULL;
 
    mShaderData = NULL;
 }

+ 12 - 1
Engine/source/T3D/fx/lightning.cpp

@@ -248,7 +248,7 @@ LightningData::LightningData()
       strikeTextureNames[i] = NULL;
       strikeTextures[i] = NULL;
    }
-
+   numThunders = 0;
    mNumStrikeTextures = 0;
 }
 
@@ -371,6 +371,7 @@ Lightning::Lightning()
    mNetFlags.set(Ghostable|ScopeAlways);
    mTypeMask |= StaticObjectType|EnvironmentObjectType;
 
+   mDataBlock = NULL;
    mLastThink = 0;
 
    mStrikeListHead  = NULL;
@@ -1033,6 +1034,16 @@ LightningBolt::LightningBolt()
    elapsedTime = 0.0f;
    lifetime = 1.0f;
    startRender = false;
+   endPoint.zero();
+   width = 1;
+   numMajorNodes = 10;
+   maxMajorAngle = 30.0f;
+   numMinorNodes = 4;
+   maxMinorAngle = 15.0f;
+   fadeTime = 0.2f;
+   renderTime = 0.125;
+   dMemset(&mMajorNodes, 0, sizeof(mMajorNodes));
+   percentFade = 0.0f;
 }
 
 //--------------------------------------------------------------------------

+ 2 - 1
Engine/source/T3D/fx/particleEmitter.cpp

@@ -846,6 +846,7 @@ ParticleEmitterData::ParticleEmitterData(const ParticleEmitterData& other, bool
    textureName = other.textureName;
    textureHandle = other.textureHandle; // -- TextureHandle loads using textureName
    highResOnly = other.highResOnly;
+   glow = other.glow;
    renderReflection = other.renderReflection;
    fade_color = other.fade_color;
    fade_size = other.fade_size;
@@ -965,7 +966,7 @@ ParticleEmitter::ParticleEmitter()
    pos_pe.set(0,0,0);
    sort_priority = 0;
    mDataBlock = 0;
-   
+   std::fill_n(sizes, ParticleData::PDC_NUM_KEYS, 0.0f);
 #if defined(AFX_CAP_PARTICLE_POOLS)
    pool = 0;
 #endif 

+ 1 - 0
Engine/source/T3D/fx/ribbon.cpp

@@ -170,6 +170,7 @@ void RibbonData::unpackData(BitStream* stream)
 //
 Ribbon::Ribbon()
 {
+   mDataBlock = NULL;
    mTypeMask |= StaticObjectType;
 
    VECTOR_SET_ASSOCIATION(mSegmentPoints);

+ 0 - 3
Engine/source/T3D/fx/ribbonNode.h

@@ -37,9 +37,6 @@ class RibbonNodeData : public GameBaseData
 {
    typedef GameBaseData Parent;
 
-public:
-   F32 timeMultiple;
-
 public:
    RibbonNodeData();
    ~RibbonNodeData();

+ 3 - 1
Engine/source/T3D/fx/splash.cpp

@@ -309,6 +309,7 @@ Splash::Splash()
 
    mDelayMS = 0;
    mCurrMS = 0;
+   mRandAngle = 0;
    mEndingMS = 1000;
    mActive = false;
    mRadius = 0.0;
@@ -319,7 +320,8 @@ Splash::Splash()
    mElapsedTime = 0.0;
 
    mInitialNormal.set( 0.0, 0.0, 1.0 );
-
+   mFade = 0;
+   mFog = 0;
    // Only allocated client side.
    mNetFlags.set( IsGhost );
 }

+ 1 - 0
Engine/source/T3D/gameBase/gameBase.cpp

@@ -254,6 +254,7 @@ GameBase::GameBase()
    mTicksSinceLastMove = 0;
    mIsAiControlled = false;
 #endif
+   mCameraFov = 90.f;
 }
 
 GameBase::~GameBase()

+ 1 - 0
Engine/source/T3D/gameBase/moveList.cpp

@@ -26,6 +26,7 @@
 
 MoveList::MoveList()
 {
+   mConnection = NULL;
    mControlMismatch = false;
    reset();
 }

+ 2 - 0
Engine/source/T3D/guiMaterialPreview.cpp

@@ -61,6 +61,8 @@ GuiMaterialPreview::GuiMaterialPreview()
    // By default don't do dynamic reflection
    // updates for this viewport.
    mReflectPriority = 0.0f;
+   mMountedModel = NULL;
+   mSkinTag = 0;
 }
 
 GuiMaterialPreview::~GuiMaterialPreview()

+ 14 - 0
Engine/source/T3D/lighting/IBLUtilities.cpp

@@ -138,6 +138,20 @@ namespace IBLUtilities
       GFXShaderConstHandle* prefilterMipSizeSC = prefilterShader->getShaderConstHandle("$mipSize");
       GFXShaderConstHandle* prefilterResolutionSC = prefilterShader->getShaderConstHandle("$resolution");
 
+      GFXStateBlockDesc desc;
+      desc.zEnable = false;
+      desc.samplersDefined = true;
+      desc.samplers[0].addressModeU = GFXAddressClamp;
+      desc.samplers[0].addressModeV = GFXAddressClamp;
+      desc.samplers[0].addressModeW = GFXAddressClamp;
+      desc.samplers[0].magFilter = GFXTextureFilterLinear;
+      desc.samplers[0].minFilter = GFXTextureFilterLinear;
+      desc.samplers[0].mipFilter = GFXTextureFilterLinear;
+
+      GFXStateBlockRef preStateBlock;
+      preStateBlock = GFX->createStateBlock(desc);
+      GFX->setStateBlock(preStateBlock);
+
       GFX->pushActiveRenderTarget();
       GFX->setShader(prefilterShader);
       GFX->setShaderConstBuffer(prefilterConsts);

+ 1 - 0
Engine/source/T3D/physics/physicsForce.cpp

@@ -43,6 +43,7 @@ ConsoleDocClass( PhysicsForce,
 PhysicsForce::PhysicsForce()
    :
       mWorld( NULL ),
+      mForce(0.0f),
       mPhysicsTick( false ),
       mBody( NULL )
 {

+ 8 - 0
Engine/source/T3D/player.cpp

@@ -311,6 +311,11 @@ PlayerData::PlayerData()
    jumpEnergyDrain = 0.0f;
    minJumpEnergy = 0.0f;
    jumpSurfaceAngle = 78.0f;
+   jumpSurfaceCos = mCos(mDegToRad(jumpSurfaceAngle));
+
+   for (U32 i = 0; i < NumRecoilSequences; i++)
+      recoilSequence[i] = -1;
+
    jumpDelay = 30;
    minJumpSpeed = 500.0f;
    maxJumpSpeed = 2.0f * minJumpSpeed;
@@ -370,6 +375,9 @@ PlayerData::PlayerData()
 
    actionCount = 0;
    lookAction = 0;
+   dMemset(spineNode, 0, sizeof(spineNode));
+
+   pickupDelta = 0.0f;
 
    // size of bounding box
    boxSize.set(1.0f, 1.0f, 2.3f);

+ 1 - 0
Engine/source/T3D/rigidShape.cpp

@@ -253,6 +253,7 @@ RigidShapeData::RigidShapeData()
 
    dustEmitter = NULL;
    dustID = 0;
+   triggerDustHeight = 3.0;
    dustHeight = 1.0;
 
    dMemset( splashEmitterList, 0, sizeof( splashEmitterList ) );

+ 1 - 1
Engine/source/T3D/shapeBase.cpp

@@ -3571,7 +3571,7 @@ Point3F ShapeBaseConvex::support(const VectorF& v) const
 void ShapeBaseConvex::getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf)
 {
    cf->material = 0;
-   cf->object = mObject;
+   cf->mObject = mObject;
 
    TSShape::ConvexHullAccelerator* pAccel =
       pShapeBase->mShapeInstance->getShape()->getAccelerator(pShapeBase->mDataBlock->collisionDetails[hullId]);

+ 1 - 1
Engine/source/T3D/shapeBase.h

@@ -111,7 +111,7 @@ class ShapeBaseConvex : public Convex
    Box3F       box;
 
   public:
-   ShapeBaseConvex() { mType = ShapeBaseConvexType; nodeTransform = 0; }
+   ShapeBaseConvex() :pShapeBase(NULL), transform(NULL), hullId(NULL), nodeTransform(0) { mType = ShapeBaseConvexType; }
    ShapeBaseConvex(const ShapeBaseConvex& cv) {
       mObject    = cv.mObject;
       pShapeBase = cv.pShapeBase;

+ 4 - 0
Engine/source/T3D/shapeImage.cpp

@@ -134,6 +134,8 @@ ShapeBaseImageData::StateData::StateData()
    recoil = NoRecoil;
    sound = 0;
    emitter = NULL;
+   shapeSequence = NULL;
+   shapeSequenceScale = true;
    script = 0;
    ignoreLoadedForReady = false;
    
@@ -1396,6 +1398,7 @@ ShapeBase::MountedImage::MountedImage()
    dataBlock = 0;
    nextImage = InvalidImagePtr;
    delayTime = 0;
+   rDT = 0.0f;
    ammo = false;
    target = false;
    triggerDown = false;
@@ -1408,6 +1411,7 @@ ShapeBase::MountedImage::MountedImage()
    motion = false;
    lightStart = 0;
    lightInfo = NULL;
+   dMemset(emitter, 0, sizeof(emitter));
 
    for (U32 i=0; i<ShapeBaseImageData::MaxGenericTriggers; ++i)
    {

+ 10 - 3
Engine/source/T3D/tsStatic.cpp

@@ -284,10 +284,17 @@ bool TSStatic::_setShapeName(void* obj, const char* index, const char* data)
          if (assetId == StringTable->insert("Core_Rendering:noShape"))
          {
             ts->mShapeName = data;
+            ts->mShapeAssetId = StringTable->EmptyString();
+
             return true;
          }
+         else
+         {
+            ts->mShapeAssetId = assetId;
+            ts->mShapeName = StringTable->EmptyString();
 
-         return false;
+            return false;
+         }
       }
     }
    else
@@ -295,7 +302,7 @@ bool TSStatic::_setShapeName(void* obj, const char* index, const char* data)
       ts->mShapeAsset = StringTable->EmptyString();
    }
 
-   return false;
+   return true;
 }
 
 bool TSStatic::_setFieldSkin(void* object, const char* index, const char* data)
@@ -1486,7 +1493,7 @@ void TSStaticPolysoupConvex::getPolyList(AbstractPolyList* list)
 void TSStaticPolysoupConvex::getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf)
 {
    cf->material = 0;
-   cf->object = mObject;
+   cf->mObject = mObject;
 
    // For a tetrahedron this is pretty easy... first
    // convert everything into world space.

+ 1 - 0
Engine/source/T3D/turret/aiTurretShape.cpp

@@ -119,6 +119,7 @@ AITurretShapeData::AITurretShapeData()
    }
    isAnimated = false;
    statesLoaded = false;
+   fireState = -1;
 }
 
 void AITurretShapeData::initPersistFields()

+ 9 - 3
Engine/source/T3D/turret/turretShape.cpp

@@ -114,17 +114,21 @@ TurretShapeData::TurretShapeData()
 
    headingNode = -1;
    pitchNode = -1;
-
-   for (U32 i=0; i<NumMirrorDirectionNodes; ++i)
+   U32 i = 0;
+   for (i=0; i<NumMirrorDirectionNodes; ++i)
    {
       pitchNodes[i] = -1;
       headingNodes[i] = -1;
    }
 
-   for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
+   for (i=0; i<ShapeBase::MaxMountedImages; ++i)
    {
       weaponMountNode[i] = -1;
    }
+   for (i = 0; i < NumRecoilSequences;i++)
+      recoilSequence[i] = -1;
+   pitchSequence = -1;
+   headingSequence = -1;
 }
 
 void TurretShapeData::initPersistFields()
@@ -284,6 +288,8 @@ TurretShape::TurretShape()
 
    // For the Item class
    mSubclassItemHandlesScene = true;
+   mRecoilThread = NULL;
+   mImageStateThread = NULL;
 }
 
 TurretShape::~TurretShape()

+ 5 - 0
Engine/source/T3D/vehicles/flyingVehicle.cpp

@@ -322,6 +322,7 @@ ConsoleDocClass( FlyingVehicle,
 
 FlyingVehicle::FlyingVehicle()
 {
+   mDataBlock = NULL;
    mSteering.set(0,0);
    mThrottle = 0;
    mJetting = false;
@@ -332,6 +333,10 @@ FlyingVehicle::FlyingVehicle()
    mBackMaintainOn = false;
    mBottomMaintainOn = false;
    createHeightOn = false;
+   mCeilingFactor = 1.0f;
+   mThrustDirection = FlyingVehicle::ThrustForward;
+   for (U32 i=0;i< JetAnimCount;i++)
+      mJetSeq[i] = -1;
 
    for (S32 i = 0; i < JetAnimCount; i++)
       mJetThread[i] = 0;

+ 0 - 1
Engine/source/T3D/vehicles/flyingVehicle.h

@@ -77,7 +77,6 @@ struct FlyingVehicleData: public VehicleData {
 
    // Initialized in preload
    ClippedPolyList rigidBody;
-   S32 surfaceCount;
    F32 maxSpeed;
 
    enum JetNodes {

+ 12 - 6
Engine/source/T3D/vehicles/hoverVehicle.cpp

@@ -139,6 +139,7 @@ HoverVehicleData::HoverVehicleData()
    dustTrailID = 0;
    dustTrailOffset.set( 0.0f, 0.0f, 0.0f );
    dustTrailFreqMod = 15.0f;
+   maxThrustSpeed = 0;
    triggerTrailHeight = 2.5f;
 
    floatingGravMag = 1;
@@ -436,24 +437,29 @@ void HoverVehicleData::unpackData(BitStream* stream)
 //
 HoverVehicle::HoverVehicle()
 {
+   mDataBlock = NULL;
    // Todo: ScopeAlways?
    mNetFlags.set(Ghostable);
 
    mFloating      = false;
-   mForwardThrust = 0;
-   mReverseThrust = 0;
-   mLeftThrust    = 0;
-   mRightThrust   = 0;
+   mThrustLevel   = 0.0f;
+   mForwardThrust = 0.0f;
+   mReverseThrust = 0.0f;
+   mLeftThrust    = 0.0f;
+   mRightThrust   = 0.0f;
 
    mJetSound    = NULL;
    mEngineSound = NULL;
    mFloatSound  = NULL;
-
+   mThrustDirection = HoverVehicle::ThrustForward;
    mDustTrailEmitter = NULL;
 
    mBackMaintainOn = false;
    for (S32 i = 0; i < JetAnimCount; i++)
-      mJetThread[i] = 0;
+   {
+      mJetSeq[i] = -1;
+      mJetThread[i] = NULL;
+   }
 }
 
 HoverVehicle::~HoverVehicle()

+ 1 - 1
Engine/source/T3D/vehicles/wheeledVehicle.cpp

@@ -304,7 +304,7 @@ WheeledVehicleData::WheeledVehicleData()
    brakeLightSequence = -1;
    steeringSequence = -1;
    wheelCount = 0;
-
+   dMemset(&wheel, 0, sizeof(wheel));
    for (S32 i = 0; i < MaxSounds; i++)
       sound[i] = 0;
 }

+ 4 - 2
Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.cpp

@@ -29,7 +29,9 @@ IMPLEMENT_CONOBJECT( VSpawnSphereSpawnTargetTrack );
 
 VSpawnSphereSpawnTargetTrack::VSpawnSphereSpawnTargetTrack( void )
 {
-    setLabel( "SpawnTargetTrack" );
+   mDespawnOnStop = false;
+   mDespawnOnLoop = false;
+   setLabel( "SpawnTargetTrack" );
 }
 
 void VSpawnSphereSpawnTargetTrack::initPersistFields( void )
@@ -152,4 +154,4 @@ void VSpawnSphereSpawnTargetTrack::despawnTargets( void )
         // Delete the Object.
         object->deleteObject();
     }
-}
+}

+ 3 - 2
Engine/source/Verve/VActor/VActorPhysicsController.cpp

@@ -49,7 +49,8 @@ VActorPhysicsController::VActorPhysicsController( void ) :
         mControlState( k_NullControlState ),
         mMoveState( k_NullMove ),
         mVelocity( VectorF::Zero ),
-        mGravity( 0.f, 0.f, -9.8f )
+        mGravity( 0.f, 0.f, -9.8f ),
+        mOnGround(false)
 {
     // Void.
 }
@@ -1274,4 +1275,4 @@ void VActorPhysicsController::unpackUpdate( NetConnection *pConnection, BitStrea
         // Apply.
         setPosition( position );
     }
-}
+}

+ 5 - 3
Engine/source/Verve/VPath/VPathEditor.h

@@ -199,7 +199,7 @@ private:
     public:
 
         VPathEditorEditPathAction( const UTF8 *pName = "" ) :
-                UndoAction( pName )
+                UndoAction( pName ), mEditor(NULL), mPath(NULL)
         {
             // Void.
         };
@@ -218,9 +218,11 @@ private:
     public:
 
         VPathEditorEditNodeAction( const UTF8 *pName = "" ) :
-                UndoAction( pName )
+                UndoAction( pName ), mEditor(NULL), mPath(NULL), mNodeIndex(0), mNodeWeight(0.0f)
         {
             // Void.
+           mNodeOrientation.Type = VPathNode::k_OrientationFree;
+           mNodeOrientation.Point = Point3F(0.0f, 0.0f, 0.0f);
         };
 
         VPathEditor               *mEditor;
@@ -290,4 +292,4 @@ namespace Utility
 
 //-----------------------------------------------------------------------------
 
-#endif // _VT_VPATHEDITOR_H_
+#endif // _VT_VPATHEDITOR_H_

+ 0 - 2
Engine/source/afx/afxCamera.h

@@ -147,8 +147,6 @@ public:
   DECLARE_CATEGORY("AFX");
 
 private:          // 3POV SECTION
-  U32             mBlockers_mask_3pov;
-
   void            cam_update_3pov(F32 dt, bool on_server);
   bool            avoid_blocked_view(const Point3F& start, const Point3F& end, Point3F& newpos);
   bool            test_blocked_line(const Point3F& start, const Point3F& end);

+ 6 - 0
Engine/source/afx/afxConstraint.cpp

@@ -1904,6 +1904,9 @@ afxEffectConstraint::afxEffectConstraint(afxConstraintMgr* mgr)
 {
   mEffect_name = ST_NULLSTRING;
   mEffect = 0;
+  mClip_tag = 0;
+  mIs_death_clip = false;
+  mLock_tag = 0;
 }
 
 afxEffectConstraint::afxEffectConstraint(afxConstraintMgr* mgr, StringTableEntry effect_name) 
@@ -1911,6 +1914,9 @@ afxEffectConstraint::afxEffectConstraint(afxConstraintMgr* mgr, StringTableEntry
 {
   mEffect_name = effect_name;
   mEffect = 0;
+  mClip_tag = 0;
+  mIs_death_clip = false;
+  mLock_tag = 0;
 }
 
 afxEffectConstraint::~afxEffectConstraint()

+ 1 - 0
Engine/source/afx/afxEffectVector.cpp

@@ -98,6 +98,7 @@ afxEffectVector::afxEffectVector()
   mOn_server = false;
   mTotal_fx_dur = 0;
   mAfter_life = 0;
+  mPhrase_dur = 0;
 }
 
 afxEffectVector::~afxEffectVector()

+ 0 - 2
Engine/source/afx/afxEffectWrapper.h

@@ -298,8 +298,6 @@ protected:
   bool              mIn_scope;
   bool              mIs_aborted;
 
-  U8                mEffect_flags;
-
   afxXM_Base*       mXfm_modifiers[MAX_XFM_MODIFIERS];
 
   F32               mLive_scale_factor;

+ 3 - 2
Engine/source/afx/afxMagicMissile.cpp

@@ -168,13 +168,14 @@ afxMagicMissileData::afxMagicMissileData()
    impactForce = 0.0f;
 
 	armingDelay = 0;
-   fadeDelay = 20000 / 32;
-   lifetime = 20000 / 32;
 
    activateSeq = -1;
    maintainSeq = -1;
    */
 
+   lifetime = 20000 / 32;
+   fadeDelay = 20000 / 32;
+
    gravityMod = 1.0;
    /* From stock Projectile code...
    bounceElasticity = 0.999f;

+ 8 - 0
Engine/source/afx/afxZodiacGroundPlaneRenderer_T3D.cpp

@@ -58,6 +58,10 @@ afxZodiacGroundPlaneRenderer::afxZodiacGroundPlaneRenderer()
    if (!master)
      master = this;
    shader_initialized = false;
+   zodiac_shader = NULL;
+   shader_consts = NULL;
+   projection_sc = NULL;
+   color_sc = NULL;
 }
 
 afxZodiacGroundPlaneRenderer::afxZodiacGroundPlaneRenderer(F32 renderOrder, F32 processAddOrder)
@@ -66,6 +70,10 @@ afxZodiacGroundPlaneRenderer::afxZodiacGroundPlaneRenderer(F32 renderOrder, F32
    if (!master)
      master = this;
    shader_initialized = false;
+   zodiac_shader = NULL;
+   shader_consts = NULL;
+   projection_sc = NULL;
+   color_sc = NULL;
 }
 
 afxZodiacGroundPlaneRenderer::~afxZodiacGroundPlaneRenderer()

+ 8 - 0
Engine/source/afx/afxZodiacMeshRoadRenderer_T3D.cpp

@@ -58,6 +58,10 @@ afxZodiacMeshRoadRenderer::afxZodiacMeshRoadRenderer()
    if (!master)
      master = this;
    shader_initialized = false;
+   zodiac_shader = NULL;
+   shader_consts = NULL;
+   projection_sc = NULL;
+   color_sc = NULL;
 }
 
 afxZodiacMeshRoadRenderer::afxZodiacMeshRoadRenderer(F32 renderOrder, F32 processAddOrder)
@@ -66,6 +70,10 @@ afxZodiacMeshRoadRenderer::afxZodiacMeshRoadRenderer(F32 renderOrder, F32 proces
    if (!master)
      master = this;
    shader_initialized = false;
+   zodiac_shader = NULL;
+   shader_consts = NULL;
+   projection_sc = NULL;
+   color_sc = NULL;
 }
 
 afxZodiacMeshRoadRenderer::~afxZodiacMeshRoadRenderer()

+ 8 - 0
Engine/source/afx/afxZodiacPolysoupRenderer_T3D.cpp

@@ -58,6 +58,10 @@ afxZodiacPolysoupRenderer::afxZodiacPolysoupRenderer()
    if (!master)
      master = this;
    shader_initialized = false;
+   zodiac_shader = NULL;
+   shader_consts = NULL;
+   projection_sc = NULL;
+   color_sc = NULL;
 }
 
 afxZodiacPolysoupRenderer::afxZodiacPolysoupRenderer(F32 renderOrder, F32 processAddOrder)
@@ -66,6 +70,10 @@ afxZodiacPolysoupRenderer::afxZodiacPolysoupRenderer(F32 renderOrder, F32 proces
    if (!master)
      master = this;
    shader_initialized = false;
+   zodiac_shader = NULL;
+   shader_consts = NULL;
+   projection_sc = NULL;
+   color_sc = NULL;
 }
 
 afxZodiacPolysoupRenderer::~afxZodiacPolysoupRenderer()

+ 8 - 0
Engine/source/afx/afxZodiacTerrainRenderer_T3D.cpp

@@ -68,6 +68,10 @@ afxZodiacTerrainRenderer::afxZodiacTerrainRenderer()
    if (!master)
      master = this;
    shader_initialized = false;
+   zodiac_shader = NULL;
+   shader_consts = NULL;
+   projection_sc = NULL;
+   color_sc = NULL;
 }
 
 afxZodiacTerrainRenderer::afxZodiacTerrainRenderer(F32 renderOrder, F32 processAddOrder)
@@ -76,6 +80,10 @@ afxZodiacTerrainRenderer::afxZodiacTerrainRenderer(F32 renderOrder, F32 processA
    if (!master)
      master = this;
    shader_initialized = false;
+   zodiac_shader = NULL;
+   shader_consts = NULL;
+   projection_sc = NULL;
+   color_sc = NULL;
 }
 
 afxZodiacTerrainRenderer::~afxZodiacTerrainRenderer()

+ 6 - 1
Engine/source/afx/ce/afxModel.cpp

@@ -105,6 +105,11 @@ afxModelData::afxModelData(const afxModelData& other, bool temp_clone) : GameBas
   customAmbientForSelfIllumination = other.customAmbientForSelfIllumination;
   customAmbientLighting = other.customAmbientLighting;
   shadowEnable = other.shadowEnable;
+
+  shadowSize = other.shadowSize;
+  shadowMaxVisibleDistance = other.shadowMaxVisibleDistance;
+  shadowProjectionDistance = other.shadowProjectionDistance;
+  shadowSphereAdjust = other.shadowSphereAdjust;
 }
 
 afxModelData::~afxModelData()
@@ -360,7 +365,7 @@ afxModel::afxModel()
   fade_amt = 1.0f;
   is_visible = true;
   sort_priority = 0;
-
+  mDataBlock = NULL;
   mNetFlags.set( IsGhost );
 }
 

+ 3 - 1
Engine/source/afx/ce/afxMooring.cpp

@@ -133,6 +133,7 @@ afxMooring::afxMooring()
   chor_id = 0;
   hookup_with_chor = false;
   ghost_cons_name = ST_NULLSTRING;
+  mDataBlock = NULL;
 }
 
 afxMooring::afxMooring(U32 networking, U32 chor_id, StringTableEntry cons_name)
@@ -160,6 +161,7 @@ afxMooring::afxMooring(U32 networking, U32 chor_id, StringTableEntry cons_name)
   this->chor_id = chor_id;
   hookup_with_chor = false;
   this->ghost_cons_name = cons_name;
+  mDataBlock = NULL;
 }
 
 afxMooring::~afxMooring()
@@ -275,4 +277,4 @@ void afxMooring::onRemove()
   Parent::onRemove();
 }
 
-//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

+ 5 - 0
Engine/source/afx/ce/afxParticleEmitter.cpp

@@ -687,6 +687,7 @@ bool afxParticleEmitterDiscData::preload(bool server, String &errorStr)
 
 afxParticleEmitter::afxParticleEmitter()
 {
+  mDataBlock = NULL;
   pe_vector.set(0,0,1);
   pe_vector_norm.set(0,0,1);
   tpaths.clear();
@@ -1086,6 +1087,7 @@ void afxParticleEmitter::emitParticlesExt(const MatrixF& xfm, const Point3F& poi
 
 afxParticleEmitterVector::afxParticleEmitterVector()
 {
+   mDataBlock = NULL;
 }
 
 afxParticleEmitterVector::~afxParticleEmitterVector()
@@ -1151,6 +1153,7 @@ void afxParticleEmitterVector::sub_preCompute(const MatrixF& mat)
 
 afxParticleEmitterCone::afxParticleEmitterCone()
 {
+  mDataBlock = NULL;
   cone_v.set(0,0,1);
   cone_s0.set(0,0,1);
   cone_s1.set(0,0,1);
@@ -1266,6 +1269,7 @@ void afxParticleEmitterCone::sub_preCompute(const MatrixF& mat)
 
 afxParticleEmitterPath::afxParticleEmitterPath()
 {
+  mDataBlock = NULL;
   epaths.clear();
   epath_mults.clear();
   n_epath_points = 0;
@@ -1521,6 +1525,7 @@ void afxParticleEmitterPath::groundConformPoint(Point3F& point, const MatrixF& m
 
 afxParticleEmitterDisc::afxParticleEmitterDisc()
 {
+  mDataBlock = NULL;
   disc_v.set(0,0,1);
   disc_r.set(1,0,0);
 }

+ 2 - 1
Engine/source/afx/ce/afxStaticShape.cpp

@@ -122,6 +122,7 @@ ConsoleDocClass( afxStaticShape,
 
 afxStaticShape::afxStaticShape()
 {
+  mDataBlock = NULL;
   mAFX_data = 0;
   mIs_visible = true;
   mChor_id = 0;
@@ -238,4 +239,4 @@ void afxStaticShape::prepRenderImage(SceneRenderState* state)
      Parent::prepRenderImage(state);
 }
 
-//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

+ 1 - 0
Engine/source/afx/ce/afxZodiac.cpp

@@ -114,6 +114,7 @@ afxZodiacData::afxZodiacData()
   grade_range_user.set(0.0f, 45.0f);
   afxZodiacData::convertGradientRangeFromDegrees(grade_range, grade_range_user);
   inv_grade_range = false;
+  zflags = 0;
 }
 
 afxZodiacData::afxZodiacData(const afxZodiacData& other, bool temp_clone) : GameBaseData(other, temp_clone)

+ 2 - 2
Engine/source/afx/ce/afxZodiacPlane.cpp

@@ -61,7 +61,7 @@ afxZodiacPlaneData::afxZodiacPlaneData()
   color.set(1,1,1,1);
   blend_flags = BLEND_NORMAL;
   respect_ori_cons = false;
-
+  zflags = 0;
   double_sided = true;
   face_dir = FACES_UP;
   use_full_xfm = false;
@@ -310,4 +310,4 @@ void afxZodiacPlane::onRemove()
   Parent::onRemove();
 }
 
-//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

+ 1 - 0
Engine/source/afx/ea/afxEA_PhraseEffect.cpp

@@ -75,6 +75,7 @@ afxEA_PhraseEffect::afxEA_PhraseEffect()
 {
   phrase_fx_data = 0;
   active_phrases = &_phrases_a;
+  last_trigger_mask = 0;
 }
 
 afxEA_PhraseEffect::~afxEA_PhraseEffect()

+ 7 - 6
Engine/source/afx/forces/afxF_Drag.cpp

@@ -60,7 +60,7 @@ class afxF_Drag : public afxForce
   typedef afxForce Parent;
 
 private:
-  afxF_DragData*  datablock;
+  afxF_DragData*  mDatablock;
   F32             air_friction_constant;
 
 public:
@@ -149,13 +149,14 @@ afxForceData* afxF_DragData::cloneAndPerformSubstitutions(const SimObject* owner
 
 afxF_Drag::afxF_Drag() : afxForce()
 {
+  mDatablock = NULL;
   air_friction_constant = 1.0f;
 }
 
 bool afxF_Drag::onNewDataBlock(afxForceData* dptr, bool reload)
 {
-  datablock = dynamic_cast<afxF_DragData*>(dptr);
-  if (!datablock || !Parent::onNewDataBlock(dptr, reload))
+   mDatablock = dynamic_cast<afxF_DragData*>(dptr);
+  if (!mDatablock || !Parent::onNewDataBlock(dptr, reload))
     return false;
 
   return true;
@@ -163,9 +164,9 @@ bool afxF_Drag::onNewDataBlock(afxForceData* dptr, bool reload)
 
 void afxF_Drag::start()
 {
-  air_friction_constant = 0.5f * datablock->drag_coefficient 
-                               * datablock->air_density 
-                               * datablock->cross_sectional_area;
+  air_friction_constant = 0.5f * mDatablock->drag_coefficient
+                               * mDatablock->air_density
+                               * mDatablock->cross_sectional_area;
   //Con::printf("Air Friction: %f", air_friction_constant);
 }
 

+ 5 - 4
Engine/source/afx/forces/afxF_Gravity.cpp

@@ -58,7 +58,7 @@ class afxF_Gravity : public afxForce
   typedef afxForce Parent;
 
 private:
-  afxF_GravityData* datablock;
+  afxF_GravityData* mDatablock;
 
 public:
   /*C*/             afxF_Gravity();
@@ -133,12 +133,13 @@ afxForceData* afxF_GravityData::cloneAndPerformSubstitutions(const SimObject* ow
 
 afxF_Gravity::afxF_Gravity() : afxForce()
 {
+   mDatablock = NULL;
 }
 
 bool afxF_Gravity::onNewDataBlock(afxForceData* dptr, bool reload)
 {
-  datablock = dynamic_cast<afxF_GravityData*>(dptr);
-  if (!datablock || !Parent::onNewDataBlock(dptr, reload))
+   mDatablock = dynamic_cast<afxF_GravityData*>(dptr);
+  if (!mDatablock || !Parent::onNewDataBlock(dptr, reload))
     return false;
 
   return true;
@@ -146,7 +147,7 @@ bool afxF_Gravity::onNewDataBlock(afxForceData* dptr, bool reload)
 
 Point3F afxF_Gravity::evaluate(Point3F pos, Point3F v, F32 mass)
 {
-  return Point3F(0,0,-datablock->gravity)*mass;
+  return Point3F(0,0,-mDatablock->gravity)*mass;
 }
 
 

+ 3 - 1
Engine/source/afx/util/afxAnimCurve.cpp

@@ -29,6 +29,8 @@
 afxAnimCurve::afxAnimCurve() : usable( false ), final_value( 0.0f ), start_value( 0.0f )
 {
 	evaluator = new afxHermiteEval();
+   final_time = 0.0f;
+   start_time = 0.0f;
 }
 
 afxAnimCurve::~afxAnimCurve()
@@ -277,4 +279,4 @@ void afxAnimCurve::printKey( int index )
 {
 	Key &k = keys[index];
 	Con::printf( "%f: %f", k.time, k.value );
-}
+}

+ 2 - 2
Engine/source/afx/util/afxCurve3D.cpp

@@ -27,7 +27,7 @@
 #include "afx/util/afxCurveEval.h"
 #include "afx/util/afxCurve3D.h"
 
-afxCurve3D::afxCurve3D() : usable( false ), default_vector( 0, 0, 0 )
+afxCurve3D::afxCurve3D() : usable( false ), default_vector( 0, 0, 0 ), flip(false)
 {
 	evaluator = new afxHermiteEval();
 }
@@ -329,4 +329,4 @@ void afxCurve3D::print()
 		Con::printf( "%f: %f %f %f", p.parameter, p.point.x, p.point.y, p.point.z );
 	}
 	Con::printf( "---------------------------------" );
-}
+}

+ 1 - 1
Engine/source/afx/util/afxPath3D.cpp

@@ -29,7 +29,7 @@
 
 #include "afx/util/afxPath3D.h"
 
-afxPath3D::afxPath3D() : mStart_time(0), mNum_points(0), mLoop_type(LOOP_CONSTANT)
+afxPath3D::afxPath3D() : mStart_time(0), mNum_points(0), mLoop_type(LOOP_CONSTANT), mEnd_time(0.0f)
 {
 }
 

+ 15 - 5
Engine/source/app/net/httpObject.cpp

@@ -114,12 +114,22 @@ ConsoleDocClass( HTTPObject,
 //--------------------------------------
 
 HTTPObject::HTTPObject()
+   : mParseState(ParsingStatusLine),
+   mTotalBytes(0),
+   mBytesRemaining(0),
+   mStatus(0),
+   mVersion(0.0f),
+   mContentLength(0),
+   mChunkedEncoding(false),
+   mChunkSize(0),
+   mContentType(""),
+   mHostName(NULL),
+   mPath(NULL),
+   mQuery(NULL),
+   mPost(NULL),
+   mBufferSave(NULL),
+   mBufferSaveSize(0)
 {
-   mHostName = 0;
-   mPath = 0;
-   mQuery = 0;
-   mPost = 0;
-   mBufferSave = 0;
 }
 
 HTTPObject::~HTTPObject()

+ 1 - 0
Engine/source/app/net/serverQuery.h

@@ -80,6 +80,7 @@ struct ServerInfo
       statusString = NULL;
       infoString = NULL;
       version = 0;
+      dMemset(&address, '\0', sizeof(NetAddress));
       ping = 0;
       cpuSpeed = 0;
       isFavorite = false;

+ 1 - 1
Engine/source/collision/boxConvex.cpp

@@ -85,7 +85,7 @@ inline bool isOnPlane(const Point3F& p,PlaneF& plane)
 void BoxConvex::getFeatures(const MatrixF& mat,const VectorF& n, ConvexFeature* cf)
 {
    cf->material = 0;
-   cf->object = mObject;
+   cf->mObject = mObject;
 
    S32 v = 0;
    v += (n.x >= 0)? 1: 0;

+ 3 - 1
Engine/source/collision/clippedPolyList.h

@@ -49,7 +49,7 @@ class ClippedPolyList : public AbstractPolyList
 public:
    struct Vertex {
       Point3F point;
-      U32 mask;
+      U32 mask = 0;
    };
 
    struct Poly {
@@ -61,6 +61,8 @@ public:
       U32 vertexCount;
       U32 surfaceKey;
 	  U32 polyFlags;
+     Poly() :object(NULL), material(NULL), vertexStart(0), vertexCount(0), surfaceKey(0), polyFlags(0) {}
+     ~Poly() {}
    };
 
    /// ???

+ 5 - 1
Engine/source/collision/collision.h

@@ -65,7 +65,11 @@ struct Collision
       object( NULL ),
       material( NULL ),
       generateTexCoord(false),
-      texCoord(-1.0f, -1.0f)
+      texCoord(-1.0f, -1.0f),
+      face(0),
+      faceDot(0.0f),
+      distance(0)
+
    {
    }
 };

+ 3 - 0
Engine/source/collision/concretePolyList.h

@@ -48,6 +48,9 @@ class ConcretePolyList : public AbstractPolyList
 
       Poly()
       {
+         vertexStart = 0;
+         vertexCount = 0;
+         surfaceKey = 0;
          object = NULL;
          material = NULL;
       }

+ 11 - 6
Engine/source/collision/convex.cpp

@@ -52,7 +52,9 @@ F32 sqrDistanceEdges(const Point3F& start0,
 
 CollisionState::CollisionState()
 {
-   mLista = mListb = 0;
+   mB = mA = NULL;
+   mDist = 0.0f;
+   mListb = mLista = 0;
 }
 
 CollisionState::~CollisionState()
@@ -85,7 +87,7 @@ F32 CollisionState::distance(const MatrixF& a2w, const MatrixF& b2w, const F32 d
 void ConvexFeature::reset()
 {
    material = NULL;
-   object = NULL;
+   mObject = NULL;
    mVertexList.clear();
    mEdgeList.clear();
    mFaceList.clear();
@@ -114,7 +116,7 @@ bool ConvexFeature::collide(ConvexFeature& cf,CollisionList* cList, F32 tol)
       {
          Collision &col = (*cList)[cList->getCount() - 1];
          col.material = cf.material;
-         col.object   = cf.object;
+         col.object   = cf.mObject;
       }
       vert++;
    }
@@ -167,7 +169,7 @@ void ConvexFeature::testVertex(const Point3F& v,CollisionList* cList,bool flip,
          if (flip)
             info.normal.neg();
          info.material = material;
-         info.object = object;
+         info.object = mObject;
          info.distance = distance;
       }
    }
@@ -213,7 +215,7 @@ void ConvexFeature::testEdge(ConvexFeature* cf,const Point3F& s1, const Point3F&
       info.normal   = normal;
       info.distance = distance;
       info.material = material;
-      info.object   = object;
+      info.object   = mObject;
    }
 }
 
@@ -282,6 +284,7 @@ CollisionWorkingList::CollisionWorkingList()
 {
    wLink.mPrev = wLink.mNext = this;
    rLink.mPrev = rLink.mNext = this;
+   mConvex = NULL;
 }
 
 void CollisionWorkingList::wLinkAfter(CollisionWorkingList* ptr)
@@ -340,6 +343,8 @@ Convex::Convex()
 {
    mNext = mPrev = this;
    mTag = 0;
+   mObject = NULL;
+   mType = ConvexType::BoxConvexType;
 }
 
 Convex::~Convex()
@@ -418,7 +423,7 @@ Point3F Convex::support(const VectorF&) const
 
 void Convex::getFeatures(const MatrixF&,const VectorF&,ConvexFeature* f)
 {
-   f->object = NULL;
+   f->mObject = NULL;
 }
 
 const MatrixF& Convex::getTransform() const

+ 2 - 2
Engine/source/collision/convex.h

@@ -56,10 +56,10 @@ public:
    Vector<Edge> mEdgeList;
    Vector<Face> mFaceList;
    BaseMatInstance* material;
-   SceneObject* object;
+   SceneObject* mObject;
 
    ConvexFeature()
-      : mVertexList(64), mEdgeList(128), mFaceList(64), material( 0 )
+      : mVertexList(64), mEdgeList(128), mFaceList(64), material( 0 ), mObject(NULL)
    {
       VECTOR_SET_ASSOCIATION(mVertexList);
       VECTOR_SET_ASSOCIATION(mEdgeList);

+ 7 - 0
Engine/source/collision/depthSortList.cpp

@@ -46,6 +46,13 @@ S32 gBadSpots = 0;
 
 DepthSortList::DepthSortList()
 {
+   mBase = 0;
+   mBasePoly = NULL;
+   mBaseNormal = NULL;
+   mBaseDot = 0.0f;
+   mBaseYMax = 0.0f;
+   mMaxTouched = 0;
+   mBaseExtents = NULL;
    VECTOR_SET_ASSOCIATION(mPolyExtentsList);
    VECTOR_SET_ASSOCIATION(mPolyIndexList);
 }

+ 1 - 0
Engine/source/collision/extrudedPolyList.cpp

@@ -47,6 +47,7 @@ ExtrudedPolyList::ExtrudedPolyList()
    mPolyPlaneList.reserve(64);
    mPlaneList.reserve(64);
    mCollisionList = 0;
+   dMemset(&mPoly, 0, sizeof(mPoly));
 }
 
 ExtrudedPolyList::~ExtrudedPolyList()

+ 5 - 2
Engine/source/collision/extrudedPolyList.h

@@ -56,13 +56,15 @@ class ExtrudedPolyList: public AbstractPolyList
 public:
    struct Vertex {
       Point3F point;
-      U32 mask;
+      U32 mask = 0;
    };
 
    struct Poly {
       PlaneF plane;
       SceneObject* object;
       BaseMatInstance* material;
+      Poly() : object(NULL), material(NULL) {}
+      ~Poly() {}
    };
 
    struct ExtrudedFace {
@@ -75,6 +77,8 @@ public:
       F32 time;
       Point3F point;
       F32 height;
+      ExtrudedFace(): active(false), maxDistance(0.0f), planeMask(0), faceDot(0.0f), faceShift(0.0f), time(0.0f), height(0.0f) {}
+      ~ExtrudedFace() {}
    };
 
    typedef Vector<ExtrudedFace> ExtrudedList;
@@ -92,7 +96,6 @@ public:
    PlaneList    mPlaneList;
    VectorF      mVelocity;
    VectorF      mNormalVelocity;
-   F32          mFaceShift;
    Poly         mPoly;
 
    // Returned info

+ 13 - 0
Engine/source/collision/gjk.cpp

@@ -46,6 +46,19 @@ S32 num_irregularities = 0;
 
 GjkCollisionState::GjkCollisionState()
 {
+   mBits = 0;
+   mAll_bits = 0;
+   U32 x, y;
+   for (x = 0; x < 16; x++)
+      for (y = 0; y < 4; y++)
+         mDet[x][y] = 0.0f;
+
+   for (x = 0; x < 4; x++)
+      for (y = 0; y < 4; y++)
+         mDP[x][y] = 0.0f;
+
+   mLast = 0;
+   mLast_bit = 0;
    mA = mB = 0;
 }
 

+ 2 - 0
Engine/source/collision/optimizedPolyList.h

@@ -88,7 +88,9 @@ class OptimizedPolyList : public AbstractPolyList
       Poly()
          : plane( -1 ),
            material( NULL ),
+           vertexStart(0),
            vertexCount( 0 ),
+           surfaceKey(0),
            object( NULL ),
            type( TriangleFan )
       {

+ 1 - 0
Engine/source/collision/planeExtractor.cpp

@@ -37,6 +37,7 @@ PlaneExtractorPolyList::PlaneExtractorPolyList()
 {
    VECTOR_SET_ASSOCIATION(mVertexList);
    VECTOR_SET_ASSOCIATION(mPolyPlaneList);
+   mPlaneList = NULL;
 }
 
 PlaneExtractorPolyList::~PlaneExtractorPolyList()

+ 1 - 0
Engine/source/collision/polytope.h

@@ -76,6 +76,7 @@ public:
       Collision()
       {
          object = NULL;
+         material = NULL;
          distance = 0.0;
       }
    };

+ 1 - 0
Engine/source/console/astNodes.cpp

@@ -142,6 +142,7 @@ StmtNode::StmtNode()
 {
    mNext = NULL;
    dbgFileName = CodeBlock::smCurrentParser->getCurrentFile();
+   dbgLineNumber = 0;
 }
 
 void StmtNode::setPackage(StringTableEntry)

+ 3 - 0
Engine/source/console/codeBlock.cpp

@@ -56,6 +56,9 @@ CodeBlock::CodeBlock()
    name = NULL;
    fullPath = NULL;
    modPath = NULL;
+   codeSize = 0;
+   lineBreakPairCount = 0;
+   nextFile = NULL;
 }
 
 CodeBlock::~CodeBlock()

+ 3 - 0
Engine/source/console/codeInterpreter.cpp

@@ -224,6 +224,9 @@ CodeInterpreter::CodeInterpreter(CodeBlock *cb) :
    mSaveCodeBlock(nullptr),
    mCurrentInstruction(0)
 {
+   dMemset(&mExec, 0, sizeof(mExec));
+   dMemset(&mObjectCreationStack, 0, sizeof(mObjectCreationStack));
+   dMemset(&mNSDocBlockClass, 0, sizeof(mNSDocBlockClass));
 }
 
 CodeInterpreter::~CodeInterpreter()

+ 1 - 1
Engine/source/console/compiler.h

@@ -317,7 +317,7 @@ protected:
       U32 addr;  ///< Address to patch
       U32 value; ///< Value to place at addr
 
-      PatchEntry() { ; }
+      PatchEntry(): addr(0), value(0) { ; }
       PatchEntry(U32 a, U32 v) : addr(a), value(v) { ; }
    } PatchEntry;
 

+ 12 - 1
Engine/source/console/consoleInternal.cpp

@@ -475,7 +475,7 @@ Dictionary::Entry::Entry(StringTableEntry in_name)
    nextEntry = NULL;
    mUsage = NULL;
    mIsConstant = false;
-
+   mNext = NULL;
    // NOTE: This is data inside a nameless
    // union, so we don't need to init the rest.
    value.init();
@@ -856,6 +856,7 @@ ExprEvalState::ExprEvalState()
    stack.reserve(64);
    mShouldReset = false;
    mResetLocked = false;
+   copyVariable = NULL;
 }
 
 ExprEvalState::~ExprEvalState()
@@ -927,6 +928,15 @@ Namespace::Entry::Entry()
    mUsage = NULL;
    mHeader = NULL;
    mNamespace = NULL;
+   cb.mStringCallbackFunc = NULL;
+   mFunctionLineNumber = 0;
+   mFunctionName = StringTable->EmptyString();
+   mFunctionOffset = 0;
+   mMinArgs = 0;
+   mMaxArgs = 0;
+   mNext = NULL;
+   mPackage = StringTable->EmptyString();
+   mToolOnly = false;
 }
 
 void Namespace::Entry::clear()
@@ -959,6 +969,7 @@ Namespace::Namespace()
    mHashSequence = 0;
    mRefCountToParent = 0;
    mClassRep = 0;
+   lastUsage = NULL;
 }
 
 Namespace::~Namespace()

+ 1 - 0
Engine/source/console/consoleInternal.h

@@ -306,6 +306,7 @@ public:
          nextEntry = NULL;
          mUsage = NULL;
          mIsConstant = false;
+         mNext = NULL;
          value.init();
       }
 

+ 16 - 1
Engine/source/console/consoleObject.h

@@ -220,7 +220,21 @@ public:
       : Parent( sizeof( void* ), conIdPtr, typeName )
    {
       VECTOR_SET_ASSOCIATION( mFieldList );
-
+      mCategory = StringTable->EmptyString();
+      mClassGroupMask = 0;
+      std::fill_n(mClassId, NetClassGroupsCount, -1);
+      mClassName = StringTable->EmptyString();
+      mClassSizeof = 0;
+      mClassType = 0;
+      mDescription = StringTable->EmptyString();
+#ifdef TORQUE_NET_STATS
+      dMemset(mDirtyMaskFrequency, 0, sizeof(mDirtyMaskFrequency));
+      dMemset(mDirtyMaskTotal, 0, sizeof(mDirtyMaskTotal));
+#endif
+      mDynamicGroupExpand = false;
+      mNamespace = NULL;
+      mNetEventDir = 0;
+      nextClass = NULL;
       parentClass  = NULL;
       mIsRenderEnabled = true;
       mIsSelectionEnabled = true;
@@ -496,6 +510,7 @@ public:
             validator( NULL ),
             setDataFn( NULL ),
             getDataFn( NULL ),
+            writeDataFn(NULL),
             networkMask(0)
       {
          doNotSubstitute = keepClearSubsOnly = false;

+ 1 - 1
Engine/source/console/engineAPI.h

@@ -1190,7 +1190,7 @@ public:
    ConsoleValueRef _exec();
    ConsoleValueRef _execLater(SimConsoleThreadExecEvent *evt);
 
-   _BaseEngineConsoleCallbackHelper() {;}
+   _BaseEngineConsoleCallbackHelper(): mThis(NULL), mInitialArgc(0), mArgc(0), mCallbackName(StringTable->EmptyString()){;}
 };
 
 

+ 2 - 1
Engine/source/console/engineExports.h

@@ -123,6 +123,7 @@ class EngineExport : public StaticEngineObject
          : mExportName( "" ),
            mExportKind( EngineExportKindScope ),
            mExportScope( NULL ),
+           mDocString(""),
            mNextExport( NULL ) {}
 };
 
@@ -165,7 +166,7 @@ class EngineExportScope : public EngineExport
    private:
    
       /// Constructor for the global scope.
-      EngineExportScope() {}
+      EngineExportScope():mExports(NULL){}
 };
 
 

+ 1 - 1
Engine/source/console/engineObject.cpp

@@ -53,7 +53,7 @@ void*& _USERDATA( EngineObject* object )
 //-----------------------------------------------------------------------------
 
 EngineObject::EngineObject()
-   : mEngineObjectUserData( NULL )
+   : mEngineObjectPool(NULL), mEngineObjectUserData( NULL )
 {
    #ifdef TORQUE_DEBUG
    // Add to instance list.

+ 1 - 0
Engine/source/console/engineTypeInfo.cpp

@@ -58,6 +58,7 @@ EngineTypeInfo::EngineTypeInfo( const char* typeName, EngineExportScope* scope,
      mEnumTable( NULL ),
      mFieldTable( NULL ),
      mPropertyTable( NULL ),
+     mArgumentTypeTable(NULL),
      mSuperType( NULL ),
      mNext( smFirst )
 {

+ 1 - 0
Engine/source/console/simDatablock.cpp

@@ -55,6 +55,7 @@ ConsoleDocClass( SimDataBlock,
 
 SimDataBlock::SimDataBlock()
 {
+   modifiedKey = 0;
    setModDynamicFields(true);
    setModStaticFields(true);
 }

+ 2 - 0
Engine/source/console/simDictionary.cpp

@@ -31,6 +31,8 @@ SimNameDictionary::SimNameDictionary()
 {
 #ifndef USE_NEW_SIMDICTIONARY
    hashTable = NULL;
+   hashTableSize = DefaultTableSize;
+   hashEntryCount = 0;
 #endif
    mutex = Mutex::createMutex();
 }

+ 1 - 1
Engine/source/console/simEvents.h

@@ -62,7 +62,7 @@ public:
    ///  of addition to the list.
    SimObject *destObject;   ///< Object on which this event will be applied.
 
-   SimEvent() { destObject = NULL; }
+   SimEvent() { nextEvent = NULL; startTime = 0; time = 0; sequenceCount = 0; destObject = NULL; }
    virtual ~SimEvent() {}   ///< Destructor
    ///
    /// A dummy virtual destructor is required

+ 2 - 2
Engine/source/console/simFieldDictionary.h

@@ -47,7 +47,7 @@ class SimFieldDictionary
 public:
    struct Entry
    {
-      Entry() : type(NULL) {};
+      Entry() : slotName(StringTable->EmptyString()), value(NULL), next(NULL), type(NULL) {};
 
       StringTableEntry slotName;
       char *value;
@@ -112,4 +112,4 @@ public:
 };
 
 
-#endif // _SIMFIELDDICTIONARY_H_
+#endif // _SIMFIELDDICTIONARY_H_

+ 4 - 0
Engine/source/console/simObject.cpp

@@ -57,6 +57,8 @@ SimObjectId SimObject::smForcedId = 0;
 
 bool SimObject::preventNameChanging = false;
 
+IMPLEMENT_CALLBACK(SimObject, onInspectPostApply, void, (SimObject* obj), (obj), "Generic callback for when an object is edited");
+
 namespace Sim
 {
    // Defined in simManager.cpp
@@ -1380,6 +1382,7 @@ SimObject::SimObject(const SimObject& other, bool temp_clone)
    nextIdObject = other.nextIdObject;
    mGroup = other.mGroup;
    mFlags = other.mFlags;
+   mProgenitorFile = other.mProgenitorFile;
    mCopySource = other.mCopySource;
    mFieldDictionary = other.mFieldDictionary;
    //mIdString = other.mIdString; // special treatment (see below)
@@ -2237,6 +2240,7 @@ void SimObject::inspectPreApply()
 
 void SimObject::inspectPostApply()
 {
+   onInspectPostApply_callback(this);
 }
 
 //-----------------------------------------------------------------------------

+ 1 - 0
Engine/source/console/simObject.h

@@ -965,6 +965,7 @@ class SimObject: public ConsoleObject, public TamlCallbacks
       virtual void getConsoleMethodData(const char * fname, S32 routingId, S32 * type, S32 * minArgs, S32 * maxArgs, void ** callback, const char ** usage) {}
       
       DECLARE_CONOBJECT( SimObject );
+      DECLARE_CALLBACK(void, onInspectPostApply, (SimObject* obj));
       
       static SimObject* __findObject( const char* id ) { return Sim::findObject( id ); }
       static const char* __getObjectId( ConsoleObject* object )

+ 6 - 0
Engine/source/console/stringStack.cpp

@@ -30,7 +30,12 @@ StringStack::StringStack()
    mBuffer = NULL;
    mArgBufferSize = 0;
    mArgBuffer = NULL;
+   for (U32 i = 0; i < MaxArgs; i++)
+      mArgV[i] = "";
+   dMemset(mFrameOffsets, 0, sizeof(mFrameOffsets));
+   dMemset(mStartOffsets, 0, sizeof(mStartOffsets));
    mNumFrames = 0;
+   mArgc = 0;
    mStart = 0;
    mLen = 0;
    mStartStackSize = 0;
@@ -232,6 +237,7 @@ mStackPos(0)
       mStack[i].init();
       mStack[i].type = ConsoleValue::TypeInternalString;
    }
+   dMemset(mStackFrames, 0, sizeof(mStackFrames));
 }
 
 ConsoleValueStack::~ConsoleValueStack()

+ 3 - 0
Engine/source/console/telnetConsole.cpp

@@ -88,6 +88,9 @@ TelnetConsole::TelnetConsole()
    mAcceptPort = -1;
    mClientList = NULL;
    mRemoteEchoEnabled = false;
+
+   dStrncpy(mTelnetPassword, "", PasswordMaxLength);
+   dStrncpy(mListenPassword, "", PasswordMaxLength);
 }
 
 TelnetConsole::~TelnetConsole()

+ 1 - 0
Engine/source/console/telnetConsole.h

@@ -78,6 +78,7 @@ class TelnetConsole
       S32 state;                       ///< State of the client.
                                        ///  @see TelnetConsole::State
       TelnetClient *nextClient;
+      TelnetClient() { dStrncpy(curLine, "", Con::MaxLineLength); curPos = 0; state = 0; nextClient = NULL; }
    };
    TelnetClient *mClientList;
    TelnetConsole();

+ 3 - 0
Engine/source/console/telnetDebugger.cpp

@@ -163,6 +163,9 @@ TelnetDebugger::TelnetDebugger()
    mProgramPaused = false;
    mWaitForClient = false;
 
+   dStrncpy(mDebuggerPassword, "", PasswordMaxLength);
+   dStrncpy(mLineBuffer, "", sizeof(mLineBuffer));
+   
    // Add the version number in a global so that
    // scripts can detect the presence of the
    // "enhanced" debugger features.

+ 2 - 1
Engine/source/console/typeValidators.h

@@ -27,7 +27,8 @@ class TypeValidator
 {
    public:
    S32 fieldIndex;
-
+   TypeValidator() : fieldIndex(0) {}
+   ~TypeValidator() {}
    /// Prints a console error message for the validator.
    ///
    /// The message is prefaced with with:

+ 2 - 1
Engine/source/core/color.h

@@ -203,7 +203,7 @@ public:
 class StockColorItem
 {
 private:
-   StockColorItem() {}
+   StockColorItem():mColorName("") {}
 
 public:
    StockColorItem( const char* pName, const U8 red, const U8 green, const U8 blue, const U8 alpha = 255 )
@@ -529,6 +529,7 @@ inline void ColorI::set(const Hsb& color)
 	red = (U32)((((F64)r) / 100) * 255);
 	green = (U32)((((F64)g) / 100) * 255);
 	blue = (U32)((((F64)b) / 100) * 255);
+   alpha = 255;
 }
 
 // This is a subfunction of HSLtoRGB

+ 1 - 0
Engine/source/core/frameAllocator.h

@@ -295,6 +295,7 @@ public:
       AssertFatal( count > 0, "Allocating a FrameTemp with less than one instance" ); \
       mWaterMark = FrameAllocator::getWaterMark(); \
       mMemory = reinterpret_cast<type *>( FrameAllocator::alloc( sizeof( type ) * count ) ); \
+      mNumObjectsInMemory = 0; \
    } \
    template<>\
    inline FrameTemp<type>::~FrameTemp() \

+ 2 - 2
Engine/source/core/ogg/oggTheoraDecoder.h

@@ -48,9 +48,9 @@ class OggTheoraFrame : public RawData
    
       typedef RawData Parent;
       
-      OggTheoraFrame() {}
+      OggTheoraFrame() :mFrameNumber(0), mFrameTime(0), mFrameDuration(0) {}
       OggTheoraFrame( S8* data, U32 size, bool ownMemory = false )
-         : Parent( data, size, ownMemory ) {}
+         : Parent( data, size, ownMemory ), mFrameNumber(0), mFrameTime(0), mFrameDuration(0) {}
          
       /// Serial number of this frame in the stream.
       U32 mFrameNumber;

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно