浏览代码

Merge branch 'ModernEditorLayoutWIP' of https://github.com/Areloch/Torque3D into development

Areloch 6 年之前
父节点
当前提交
3697737498
共有 100 个文件被更改,包括 2679 次插入605 次删除
  1. 23 3
      Engine/source/T3D/tsStatic.cpp
  2. 2 0
      Engine/source/T3D/tsStatic.h
  3. 47 5
      Engine/source/gui/controls/guiTreeViewCtrl.cpp
  4. 9 1
      Engine/source/gui/controls/guiTreeViewCtrl.h
  5. 2 0
      Engine/source/materials/baseMatInstance.h
  6. 9 1
      Engine/source/materials/customShaderBindingData.h
  7. 34 0
      Engine/source/materials/matInstance.cpp
  8. 2 1
      Engine/source/materials/matInstance.h
  9. 7 1
      Engine/source/materials/materialDefinition.cpp
  10. 41 0
      Engine/source/materials/materialManager.cpp
  11. 3 0
      Engine/source/materials/materialManager.h
  12. 3 0
      Engine/source/materials/processedMaterial.h
  13. 24 1
      Engine/source/materials/processedShaderMaterial.cpp
  14. 1 0
      Engine/source/materials/processedShaderMaterial.h
  15. 5 6
      Engine/source/renderInstance/renderDeferredMgr.cpp
  16. 350 0
      Engine/source/shaderGen/GLSL/customFeatureGLSL.cpp
  17. 132 0
      Engine/source/shaderGen/GLSL/customFeatureGLSL.h
  18. 424 395
      Engine/source/shaderGen/HLSL/customFeatureHLSL.cpp
  19. 97 88
      Engine/source/shaderGen/HLSL/customFeatureHLSL.h
  20. 84 73
      Engine/source/shaderGen/customShaderFeature.cpp
  21. 5 3
      Engine/source/shaderGen/customShaderFeature.h
  22. 43 24
      Engine/source/shaderGen/shaderGen.cpp
  23. 207 0
      Templates/BaseGame/game/tools/MainEditor/MainEditor.cs
  24. 9 0
      Templates/BaseGame/game/tools/MainEditor/MainEditor.module
  25. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/Button.png
  26. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/GroupBackground.png
  27. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/GroupBackground_h.png
  28. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/GroupBackground_i.png
  29. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/PropertyRollout.png
  30. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/ScrollBar.png
  31. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/ScrollBar_.png
  32. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/Spacer.png
  33. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddEvent.png
  34. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddEvent_d.png
  35. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddEvent_h.png
  36. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddGroup.png
  37. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddGroup_d.png
  38. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddGroup_h.png
  39. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddL.png
  40. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddL_d.png
  41. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddL_h.png
  42. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddR.png
  43. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddR_d.png
  44. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddR_h.png
  45. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddSml.png
  46. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddSml_d.png
  47. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddSml_h.png
  48. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddTrack.png
  49. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddTrack_d.png
  50. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_AddTrack_h.png
  51. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Delete.png
  52. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_DeleteSml.png
  53. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_DeleteSml_d.png
  54. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_DeleteSml_h.png
  55. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Delete_d.png
  56. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Delete_h.png
  57. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Forward.png
  58. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Forward_d.png
  59. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Forward_h.png
  60. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Palette_d.png
  61. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Palette_h.png
  62. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Palette_n.png
  63. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Pause.png
  64. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Pause_d.png
  65. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Pause_h.png
  66. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Play.png
  67. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Play_d.png
  68. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Play_h.png
  69. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Rewind.png
  70. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Rewind_d.png
  71. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_Rewind_h.png
  72. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_StepB.png
  73. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_StepB_d.png
  74. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_StepB_h.png
  75. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_StepF.png
  76. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_StepF_d.png
  77. 二进制
      Templates/BaseGame/game/tools/MainEditor/art/btn_StepF_h.png
  78. 485 0
      Templates/BaseGame/game/tools/MainEditor/guis/MainEditorWindow.gui
  79. 213 0
      Templates/BaseGame/game/tools/MainEditor/scripts/GuiProfiles.cs
  80. 103 0
      Templates/BaseGame/game/tools/MainEditor/scripts/newEditorGui.cs
  81. 26 0
      Templates/BaseGame/game/tools/Tools.cs
  82. 8 0
      Templates/BaseGame/game/tools/Tools.module
  83. 4 0
      Templates/BaseGame/game/tools/gui/profiles.ed.cs
  84. 7 0
      Templates/BaseGame/game/tools/main.cs
  85. 24 3
      Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui
  86. 4 0
      Templates/BaseGame/game/tools/materialEditor/main.cs
  87. 26 0
      Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.cs
  88. 207 0
      Templates/Full/game/tools/MainEditor/MainEditor.cs
  89. 9 0
      Templates/Full/game/tools/MainEditor/MainEditor.module
  90. 二进制
      Templates/Full/game/tools/MainEditor/art/Button.png
  91. 二进制
      Templates/Full/game/tools/MainEditor/art/GroupBackground.png
  92. 二进制
      Templates/Full/game/tools/MainEditor/art/GroupBackground_h.png
  93. 二进制
      Templates/Full/game/tools/MainEditor/art/GroupBackground_i.png
  94. 二进制
      Templates/Full/game/tools/MainEditor/art/PropertyRollout.png
  95. 二进制
      Templates/Full/game/tools/MainEditor/art/ScrollBar.png
  96. 二进制
      Templates/Full/game/tools/MainEditor/art/ScrollBar_.png
  97. 二进制
      Templates/Full/game/tools/MainEditor/art/Spacer.png
  98. 二进制
      Templates/Full/game/tools/MainEditor/art/btn_AddEvent.png
  99. 二进制
      Templates/Full/game/tools/MainEditor/art/btn_AddEvent_d.png
  100. 二进制
      Templates/Full/game/tools/MainEditor/art/btn_AddEvent_h.png

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

@@ -680,10 +680,30 @@ void TSStatic::prepRenderImage( SceneRenderState* state )
    rdata.setAccuTex(mAccuTex);
 
    //Various arbitrary shader render bits to add
-   CustomShaderBindingData strudelCSB;
-   strudelCSB.setFloat4(StringTable->insert("overrideColor"), mOverrideColor);
+   if (mCustomShaderBinds.empty())
+   {
+      CustomShaderBindingData minBnds;
+      minBnds.setFloat3(StringTable->insert("objectBoundsMin"), getWorldBox().minExtents);
+      mCustomShaderBinds.push_back(minBnds);
+
+      CustomShaderBindingData maxBnds;
+      maxBnds.setFloat3(StringTable->insert("objectBoundsMax"), getWorldBox().maxExtents);
+      mCustomShaderBinds.push_back(maxBnds);
 
-   rdata.addCustomShaderBinding(strudelCSB);
+      CustomShaderBindingData colorMin;
+      colorMin.setFloat3(StringTable->insert("colorMin"), Point3F(1,0,0));
+      mCustomShaderBinds.push_back(colorMin);
+
+      CustomShaderBindingData colorMax;
+      colorMax.setFloat3(StringTable->insert("colorMax"), Point3F(0, 1, 0));
+      mCustomShaderBinds.push_back(colorMax);
+   }
+
+   if (!mCustomShaderBinds.empty())
+   {
+      for(U32 i=0; i < mCustomShaderBinds.size(); i++)
+         rdata.addCustomShaderBinding(mCustomShaderBinds[i]);
+   }
 
    // If we have submesh culling enabled then prepare
    // the object space frustum to pass to the shape.

+ 2 - 0
Engine/source/T3D/tsStatic.h

@@ -203,6 +203,8 @@ protected:
    F32 mRenderNormalScalar;
    S32 mForceDetail;
 
+   Vector<CustomShaderBindingData> mCustomShaderBinds;
+
 public:
 
    TSStatic();

+ 47 - 5
Engine/source/gui/controls/guiTreeViewCtrl.cpp

@@ -832,6 +832,8 @@ GuiTreeViewCtrl::GuiTreeViewCtrl()
    mTexSelected      = NULL;
    
    mRenderTooltipDelegate.bind( this, &GuiTreeViewCtrl::renderTooltip );
+
+   mDoFilterChildren = true;
 }
 
 //-----------------------------------------------------------------------------
@@ -1122,7 +1124,7 @@ void GuiTreeViewCtrl::_expandObjectHierarchy( SimGroup* group )
 
 //------------------------------------------------------------------------------
 
-void GuiTreeViewCtrl::_buildItem( Item* item, U32 tabLevel, bool bForceFullUpdate )
+void GuiTreeViewCtrl::_buildItem( Item* item, U32 tabLevel, bool bForceFullUpdate, bool skipFlter )
 {
    if (!item || !mActive || !isVisible() || !mProfile  )
       return;
@@ -1145,7 +1147,7 @@ void GuiTreeViewCtrl::_buildItem( Item* item, U32 tabLevel, bool bForceFullUpdat
 
    // If we have a filter pattern, sync the item's filtering status to it.
 
-   if( !getFilterText().isEmpty() )
+   if( !getFilterText().isEmpty() && !skipFlter)
    {
       // Determine the filtering status by looking for the filter
       // text in the item's display text.
@@ -1154,7 +1156,11 @@ void GuiTreeViewCtrl::_buildItem( Item* item, U32 tabLevel, bool bForceFullUpdat
       item->getDisplayText( sizeof( displayText ), displayText );
       if( !dStristr( displayText, mFilterText ) )
       {
-         item->mState.set( Item::Filtered );
+         //Last check, see if we special-exception this item
+         if (!mItemFilterExceptionList.contains(item->mId))
+            item->mState.set(Item::Filtered);
+         else
+            item->mState.clear(Item::Filtered);
 
          // If it's not a parent, we're done.  Otherwise, there may be children
          // that are not filtered so we need to process them first.
@@ -1163,7 +1169,9 @@ void GuiTreeViewCtrl::_buildItem( Item* item, U32 tabLevel, bool bForceFullUpdat
             return;
       }
       else
-         item->mState.clear( Item::Filtered );
+      {
+         item->mState.clear(Item::Filtered);
+      }
    }
    else
       item->mState.clear( Item::Filtered );
@@ -1217,7 +1225,10 @@ void GuiTreeViewCtrl::_buildItem( Item* item, U32 tabLevel, bool bForceFullUpdat
          Item *pChildTemp = child;
          child = child->mNext;
 
-         _buildItem( pChildTemp, tabLevel + 1, bForceFullUpdate );
+         if (!mItemFilterExceptionList.contains(item->mId) && !mDoFilterChildren && !item->isFiltered())
+            _buildItem( pChildTemp, tabLevel + 1, bForceFullUpdate, true );
+         else
+            _buildItem(pChildTemp, tabLevel + 1, bForceFullUpdate, false);
       }
    }
 }
@@ -4775,6 +4786,18 @@ void GuiTreeViewCtrl::setFilterText( const String& text )
    mFlags.set( RebuildVisible );
 }
 
+void GuiTreeViewCtrl::setItemFilterException(U32 item, bool isExempted)
+{
+   if (isExempted)
+   {
+      mItemFilterExceptionList.push_back(item);
+   }
+   else
+   {
+      mItemFilterExceptionList.remove(item);
+   }
+}
+
 //=============================================================================
 //    Console Methods.
 //=============================================================================
@@ -5574,6 +5597,25 @@ DefineEngineMethod( GuiTreeViewCtrl, setFilterText, void, ( const char* pattern
    object->setFilterText( pattern );
 }
 
+DefineEngineMethod(GuiTreeViewCtrl, setFilterChildren, void, (bool doFilterChildren), (true),
+   "Set the pattern by which to filter items in the tree.  Only items in the tree whose text "
+   "matches this pattern are displayed.\n\n"
+   "@param pattern New pattern based on which visible items in the tree should be filtered.  If empty, all items become visible.\n\n"
+   "@see getFilterText\n"
+   "@see clearFilterText")
+{
+   object->setFilterChildren(doFilterChildren);
+}
+
+DefineEngineMethod(GuiTreeViewCtrl, setItemFilterException, void, (U32 item, bool isExempt), (0, true),
+   "Set the pattern by which to filter items in the tree.  Only items in the tree whose text "
+   "matches this pattern are displayed.\n\n"
+   "@param pattern New pattern based on which visible items in the tree should be filtered.  If empty, all items become visible.\n\n"
+   "@see getFilterText\n"
+   "@see clearFilterText")
+{
+   object->setItemFilterException(item, isExempt);
+}
 //-----------------------------------------------------------------------------
 
 DefineEngineMethod( GuiTreeViewCtrl, clearFilterText, void, (),,

+ 9 - 1
Engine/source/gui/controls/guiTreeViewCtrl.h

@@ -356,6 +356,11 @@ class GuiTreeViewCtrl : public GuiArrayCtrl
       /// Current filter that determines which items in the tree are displayed and which are hidden.
       String mFilterText;
 
+      /// If true, all items are filtered. If false, then children of items that successfully pass filter are not filtered
+      bool mDoFilterChildren;
+
+      Vector<U32> mItemFilterExceptionList;
+
       /// If true, a trace of actions taken by the control is logged to the console.  Can
       /// be turned on with the setDebug() script method.
       bool mDebug;
@@ -431,7 +436,7 @@ class GuiTreeViewCtrl : public GuiArrayCtrl
 
       void _deleteItem(Item* item);
 
-      void _buildItem(Item* item, U32 tabLevel, bool bForceFullUpdate = false);
+      void _buildItem(Item* item, U32 tabLevel, bool bForceFullUpdate = false, bool skipFlter = false);
 
       Item* _findItemByAmbiguousId( S32 itemOrObjectId, bool buildVirtual = true );
 
@@ -569,6 +574,9 @@ class GuiTreeViewCtrl : public GuiArrayCtrl
       /// matches this pattern are displayed.
       void setFilterText( const String& text );
 
+      void setFilterChildren(bool doFilter) { mDoFilterChildren = doFilter; }
+      void setItemFilterException(U32 item, bool isExempt);
+
       /// Clear the current item filtering pattern.
       void clearFilterText() { setFilterText( String::EmptyString ); }
 

+ 2 - 0
Engine/source/materials/baseMatInstance.h

@@ -66,6 +66,7 @@ struct GFXStateBlockDesc;
 class GFXVertexFormat;
 class MatrixSet;
 class ProcessedMaterial;
+class GuiTreeViewCtrl;
 
 ///
 class BaseMatInstance
@@ -225,6 +226,7 @@ public:
    virtual const GFXVertexFormat* getVertexFormat() const = 0;
 
    virtual void dumpShaderInfo() const = 0;
+   virtual void getShaderInfo(GuiTreeViewCtrl* tree, U32 item) const = 0;
 
    /// Fast test for use of normal maps in this material.
    bool hasNormalMap() const { return mHasNormalMaps; }

+ 9 - 1
Engine/source/materials/customShaderBindingData.h

@@ -77,6 +77,14 @@ public:
 	}
 	Point4F getFloat4() { return mFloat4; }
 
+   void setTexture2D(StringTableEntry shaderConstName, GFXTexHandle f)
+   {
+      targetedUniformName = shaderConstName;
+      texture = f;
+      type = Texture2D;
+   }
+   GFXTexHandle getTexture2D() { return texture; }
+
 	StringTableEntry getHandleName() {
 		return targetedUniformName;
 	}
@@ -86,4 +94,4 @@ public:
 	}
 };
 
-#endif
+#endif

+ 34 - 0
Engine/source/materials/matInstance.cpp

@@ -37,6 +37,8 @@
 #include "core/util/safeDelete.h"
 #include "ts/tsShape.h"
 
+#include "gui/controls/guiTreeViewCtrl.h"
+
 class MatInstParameters;
 
 class MatInstanceParameterHandle : public MaterialParameterHandle
@@ -598,3 +600,35 @@ void MatInstance::dumpShaderInfo() const
 
    mProcessedMaterial->dumpMaterialInfo();
 }
+
+void MatInstance::getShaderInfo(GuiTreeViewCtrl* tree, U32 item) const
+{
+   if (mMaterial == NULL)
+   {
+      Con::errorf("Trying to get Material information on an invalid MatInstance");
+      return;
+   }
+
+   if (mProcessedMaterial == NULL)
+   {
+      Con::printf("  [no processed material!]");
+      return;
+   }
+
+   const FeatureSet features = mProcessedMaterial->getFeatures();
+
+   String featureDesc = "";
+   for (U32 i = 0; i < features.getCount(); i++)
+   {
+      const FeatureType& ft = features.getAt(i);
+
+      featureDesc += ft.getName();
+
+      if(i+1 < features.getCount())
+         featureDesc += ", ";
+   }
+
+   U32 newItem = tree->insertItem(item, featureDesc);
+
+   mProcessedMaterial->getMaterialInfo(tree, newItem);
+}

+ 2 - 1
Engine/source/materials/matInstance.h

@@ -44,7 +44,7 @@ class ShaderFeature;
 class MatInstanceParameterHandle;
 class MatInstParameters;
 class ProcessedMaterial;
-
+class GuiTreeViewCtrl;
 
 ///
 class MatInstance : public BaseMatInstance
@@ -87,6 +87,7 @@ public:
    virtual const FeatureSet& getFeatures() const;
    virtual const FeatureSet& getRequestedFeatures() const { return mFeatureList; }
    virtual void dumpShaderInfo() const;
+   virtual void getShaderInfo(GuiTreeViewCtrl* tree, U32 item) const;
    
 
    ProcessedMaterial *getProcessedMaterial() const { return mProcessedMaterial; }

+ 7 - 1
Engine/source/materials/materialDefinition.cpp

@@ -36,7 +36,7 @@
 #include "sfx/sfxTypes.h"
 #include "core/util/safeDelete.h"
 #include "T3D/accumulationVolume.h"
-
+#include "gui/controls/guiTreeViewCtrl.h"
 
 IMPLEMENT_CONOBJECT( Material );
 
@@ -709,6 +709,12 @@ DefineEngineMethod( Material, dumpInstances, void, (),,
    MATMGR->dumpMaterialInstances( object );
 }
 
+DefineEngineMethod(Material, getMaterialInstances, void, (GuiTreeViewCtrl* matTree), (nullAsType< GuiTreeViewCtrl*>()),
+   "Dumps a formatted list of the currently allocated material instances for this material to the console.")
+{
+   MATMGR->getMaterialInstances(object, matTree);
+}
+
 DefineEngineMethod( Material, getAnimFlags, const char*, (U32 id), , "" )
 {
    char * animFlags = Con::getReturnBuffer(512);

+ 41 - 0
Engine/source/materials/materialManager.cpp

@@ -32,6 +32,7 @@
 #include "console/consoleTypes.h"
 #include "console/engineAPI.h"
 
+#include "gui/controls/guiTreeViewCtrl.h"
 
 MODULE_BEGIN( MaterialManager )
 
@@ -397,6 +398,36 @@ void MaterialManager::dumpMaterialInstances( BaseMaterialDefinition *target ) co
    Con::printf( "---------------------- Dump complete ----------------------");
 }
 
+void MaterialManager::getMaterialInstances(BaseMaterialDefinition* target, GuiTreeViewCtrl* materailInstanceTree)
+{
+   if (!mMatInstanceList.size())
+      return;
+
+   if (!target)
+   {
+      Con::errorf("Can't form a list without a specific MaterialDefinition");
+      return;
+   }
+
+   if (!materailInstanceTree)
+   {
+      Con::errorf("Requires a valid GuiTreeViewCtrl object to populate data into!");
+      return;
+   }
+
+   U32 matItem = materailInstanceTree->insertItem(0, target->getName());
+
+   for (U32 i = 0; i < mMatInstanceList.size(); i++)
+   {
+      BaseMatInstance* inst = mMatInstanceList[i];
+
+      if (target && inst->getMaterial() != target)
+         continue;
+
+      inst->getShaderInfo(materailInstanceTree, matItem);
+   }
+}
+
 void MaterialManager::_track( MatInstance *matInstance )
 {
    mMatInstanceList.push_back( matInstance );
@@ -480,6 +511,16 @@ DefineEngineFunction( dumpMaterialInstances, void, (), ,
    MATMGR->dumpMaterialInstances();
 }
 
+DefineEngineFunction(getMaterialInstances, void, (BaseMaterialDefinition* target, GuiTreeViewCtrl* tree), (nullAsType<BaseMaterialDefinition*>(), nullAsType<GuiTreeViewCtrl*>()),
+   "@brief Dumps a formatted list of currently allocated material instances to the console.\n\n"
+   "@ingroup Materials")
+{
+   if (target == nullptr || tree == nullptr)
+      return;
+
+   MATMGR->getMaterialInstances(target, tree);
+}
+
 DefineEngineFunction( getMapEntry, const char*, (const char * texName), ,
    "@hide")
 {

+ 3 - 0
Engine/source/materials/materialManager.h

@@ -37,6 +37,7 @@
 
 class SimSet;
 class MatInstance;
+class GuiTreeViewCtrl;
 
 class MaterialManager : public ManagedSingleton<MaterialManager>
 {
@@ -97,6 +98,8 @@ public:
 
    void dumpMaterialInstances( BaseMaterialDefinition *target = NULL ) const;
 
+   void getMaterialInstances(BaseMaterialDefinition* target, GuiTreeViewCtrl* tree);
+
    void updateTime();
    F32 getTotalTime() const { return mAccumTime; }
    F32 getDeltaTime() const { return mDt; }

+ 3 - 0
Engine/source/materials/processedMaterial.h

@@ -50,6 +50,7 @@ class SceneRenderState;
 class GFXVertexBufferHandleBase;
 class GFXPrimitiveBufferHandle;
 class MatrixSet;
+class GuiTreeViewCtrl;
 
 /// This contains the common data needed to render a pass.
 struct RenderPassData
@@ -226,6 +227,8 @@ public:
    /// Dump shader info, or FF texture info?
    virtual void dumpMaterialInfo() { }
 
+   virtual void getMaterialInfo(GuiTreeViewCtrl* tree, U32 item) {}
+
    /// Returns the source material.
    Material* getMaterial() const { return mMaterial; }
 

+ 24 - 1
Engine/source/materials/processedShaderMaterial.cpp

@@ -48,7 +48,7 @@
 // We need to include customMaterialDefinition for ShaderConstHandles::init
 #include "materials/customMaterialDefinition.h"
 
-
+#include "gui/controls/guiTreeViewCtrl.h"
 #include "ts/tsShape.h"
 
 ///
@@ -1534,3 +1534,26 @@ void ProcessedShaderMaterial::dumpMaterialInfo()
          Con::printf( "  [%i] %s", i, shader->describeSelf().c_str() );
    }
 }
+
+void ProcessedShaderMaterial::getMaterialInfo(GuiTreeViewCtrl* tree, U32 item)
+{
+   for (U32 i = 0; i < getNumPasses(); i++)
+   {
+      const ShaderRenderPassData* passData = _getRPD(i);
+
+      if (passData == NULL)
+         continue;
+
+      char passStr[64];
+      dSprintf(passStr, 64, "Pass Number: %i", i);
+
+      U32 passItem = tree->insertItem(item, passStr);
+
+      const GFXShader * shader = passData->shader;
+
+      if (shader == NULL)
+         tree->insertItem(passItem, "[NULL shader]");
+      else
+         tree->insertItem(passItem, shader->describeSelf().c_str());
+   }
+}

+ 1 - 0
Engine/source/materials/processedShaderMaterial.h

@@ -149,6 +149,7 @@ public:
    virtual void setBuffers(GFXVertexBufferHandleBase* vertBuffer, GFXPrimitiveBufferHandle* primBuffer); 
    virtual bool stepInstance();
    virtual void dumpMaterialInfo();
+   virtual void getMaterialInfo(GuiTreeViewCtrl* tree, U32 item);
    virtual MaterialParameters* allocMaterialParameters();    
    virtual MaterialParameters* getDefaultMaterialParameters() { return mDefaultParameters; }   
    virtual MaterialParameterHandle* getMaterialParameterHandle(const String& name);

+ 5 - 6
Engine/source/renderInstance/renderDeferredMgr.cpp

@@ -424,12 +424,11 @@ void RenderDeferredMgr::render( SceneRenderState *state )
                mat->setNodeTransforms(passRI->mNodeTransforms, passRI->mNodeTransformCount);
             }
 
-			//-JR
-			//push along any overriden fields that are instance-specific as well
-			if (passRI->mCustomShaderData.size() > 0)
-			{
-				mat->setCustomShaderData(passRI->mCustomShaderData);
-			}
+			   //push along any overriden fields that are instance-specific as well
+			   if (passRI->mCustomShaderData.size() > 0)
+			   {
+				   mat->setCustomShaderData(passRI->mCustomShaderData);
+			   }
 
             // If we're instanced then don't render yet.
             if ( mat->isInstanced() )

+ 350 - 0
Engine/source/shaderGen/GLSL/customFeatureGLSL.cpp

@@ -0,0 +1,350 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "customFeatureGLSL.h"
+#include "shaderGen/shaderFeature.h"
+#include "shaderGen/shaderOp.h"
+#include "shaderGen/featureMgr.h"
+//#include "materials/materialFeatureTypes.h"
+//#include "gfx/gfxDevice.h"
+//#include "materials/processedMaterial.h"
+
+//****************************************************************************
+// Accu Texture
+//****************************************************************************
+void CustomFeatureGLSL::processVert(Vector<ShaderComponent*>& componentList,
+   const MaterialFeatureData& fd)
+{
+   meta = new MultiLine;
+
+   mFeatureData = fd;
+   mComponentList = componentList;
+
+   mOutputState = VertexOutput;
+
+   if (mOwner->isMethod("processVertGLSL"))
+      Con::executef(mOwner, "processVertGLSL");
+
+   output = meta;
+}
+
+void CustomFeatureGLSL::processPix(Vector<ShaderComponent*>& componentList,
+   const MaterialFeatureData& fd)
+{
+   meta = new MultiLine;
+
+   mFeatureData = fd;
+   mComponentList = componentList;
+
+   mOutputState = PixelOutput;
+
+   if (mOwner->isMethod("processPixelGLSL"))
+      Con::executef(mOwner, "processPixelGLSL");
+
+   output = meta;
+}
+
+void CustomFeatureGLSL::setTexData(Material::StageData& stageDat,
+   const MaterialFeatureData& fd,
+   RenderPassData& passData,
+   U32& texIndex)
+{
+
+   if (mOwner->isMethod("setTextureData"))
+      Con::executef(mOwner, "setTextureData");
+}
+
+void CustomFeatureGLSL::addUniform(String name, String type, String defaultValue, U32 arraySize)
+{
+   //do the var/arg fetching here
+   Var* newVar = (Var*)LangElement::find(name.c_str());
+   if (!newVar)
+   {
+      VarHolder newVarHolder(name, type, "");
+      newVarHolder.arraySize = arraySize;
+      newVarHolder.sampler = false;
+      newVarHolder.uniform = true;
+      newVarHolder.constSortPos = cspPotentialPrimitive;
+
+      mVars.push_back(newVarHolder);
+
+      mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str()));
+   }
+}
+
+void CustomFeatureGLSL::addSampler(String name, String type, U32 arraySize)
+{
+   //do the var/arg fetching here
+   Var* newVar = (Var*)LangElement::find(name.c_str());
+   if (!newVar)
+   {
+      //As far as I know, it's always SamplerState regardless of the texture's type
+      VarHolder newVarHolder(name, "SamplerState", "");
+      newVarHolder.arraySize = arraySize;
+      newVarHolder.sampler = true;
+      newVarHolder.uniform = true;
+      newVarHolder.constNum = Var::getTexUnitNum();     // used as texture unit num here
+
+      mVars.push_back(newVarHolder);
+
+      mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str()));
+   }
+}
+
+void CustomFeatureGLSL::addTexture(String name, String type, String samplerState, U32 arraySize)
+{
+   //do the var/arg fetching here
+   Var* newVar = (Var*)LangElement::find(name.c_str());
+   if (!newVar)
+   {
+      //go find our sampler state var
+      U32 constNum = 0;
+
+      Var* samplerStateVar = (Var*)LangElement::find(samplerState.c_str());
+      if (!samplerStateVar)
+      {
+         //check our holder vars
+         bool foundHolder = false;
+         for (U32 v = 0; v < mVars.size(); v++)
+         {
+            if (mVars[v].varName == samplerState)
+            {
+               constNum = mVars[v].constNum;
+               foundHolder = true;
+               break;
+            }
+         }
+
+         if (!foundHolder)
+         {
+            Con::errorf("CustomShaderFeature::addTexture: Unable to find texture's sampler state!");
+            return;
+         }
+      }
+      else
+      {
+         constNum = samplerStateVar->constNum;
+      }
+
+      VarHolder newVarHolder(name, type, "");
+      newVarHolder.arraySize = arraySize;
+      newVarHolder.texture = true;
+      newVarHolder.uniform = true;
+      newVarHolder.constNum = constNum;     // used as texture unit num here
+
+      mVars.push_back(newVarHolder);
+
+      mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str()));
+   }
+}
+
+void CustomFeatureGLSL::addVariable(String name, String type, String defaultValue)
+{
+   //do the var/arg fetching here
+   Var* newVar = (Var*)LangElement::find(name.c_str());
+   if (!newVar)
+   {
+      if (!defaultValue.isEmpty())
+      {
+         char declareStatement[128];
+         dSprintf(declareStatement, 128, "   @ = %s;\n", defaultValue.c_str());
+
+         newVar = new Var(name, type);
+         LangElement* newVarDecl = new DecOp(newVar);
+         meta->addStatement(new GenOp(declareStatement, newVarDecl));
+      }
+      else
+      {
+         VarHolder newVarHolder(name, type, defaultValue);
+
+         mVars.push_back(newVarHolder);
+      }
+   }
+}
+
+void CustomFeatureGLSL::addConnector(String name, String type, String elementName)
+{
+   // grab connector texcoord register
+   ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(mComponentList[C_CONNECTOR]);
+
+   //Get element
+   S32 element = -1;
+
+   if (elementName == String("RT_POSITION"))
+      element = RT_POSITION;
+   else if (elementName == String("RT_NORMAL"))
+      element = RT_NORMAL;
+   else if (elementName == String("RT_BINORMAL"))
+      element = RT_BINORMAL;
+   else if (elementName == String("RT_TANGENT"))
+      element = RT_TANGENT;
+   else if (elementName == String("RT_TANGENTW"))
+      element = RT_TANGENTW;
+   else if (elementName == String("RT_COLOR"))
+      element = RT_COLOR;
+   else if (elementName == String("RT_TEXCOORD"))
+      element = RT_TEXCOORD;
+   else if (elementName == String("RT_VPOS"))
+      element = RT_VPOS;
+   else if (elementName == String("RT_SVPOSITION"))
+      element = RT_SVPOSITION;
+   else if (elementName == String("RT_BLENDINDICES"))
+      element = RT_BLENDINDICES;
+   else if (elementName == String("RT_BLENDWEIGHT"))
+      element = RT_BLENDWEIGHT;
+
+   if (element == -1)
+   {
+      Con::errorf("CustomShaderFeatureHLSL::addConnector - Invalid element type %s", elementName.c_str());
+      return;
+   }
+
+   VarHolder newVarHolder(name, type, "");
+
+   newVarHolder.elementId = element;
+
+   if (mOutputState == VertexOutput)
+      newVarHolder.structName = "OUT";
+   else if (mOutputState == PixelOutput)
+      newVarHolder.structName = "IN";
+
+   mVars.push_back(newVarHolder);
+}
+
+void CustomFeatureGLSL::addVertTexCoord(String name)
+{
+   VarHolder newVarHolder(name, "", "");
+   newVarHolder.texCoord = true;
+
+   mVars.push_back(newVarHolder);
+}
+
+void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValueRef * argv)
+{
+   //do the var/arg fetching here
+   Vector<Var*> varList;
+   bool declarationStatement = false;
+
+   for (U32 i = 0; i < argc; i++)
+   {
+      String varName = argv[i].getStringValue();
+      Var* newVar = (Var*)LangElement::find(varName.c_str());
+      if (!newVar)
+      {
+         //ok, check our existing var holders, see if we just haven't utilized it yet
+         for (U32 v = 0; v < mVars.size(); v++)
+         {
+            if (mVars[v].varName == varName)
+            {
+               if (!mVars[v].texCoord)
+               {
+                  if (mVars[v].elementId != -1)
+                  {
+                     ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(mComponentList[C_CONNECTOR]);
+                     Var* newDeclVar = connectComp->getElement((RegisterType)mVars[v].elementId);
+                     newDeclVar->setName(mVars[v].varName);
+                     newDeclVar->setStructName(mVars[v].structName);
+                     newDeclVar->setType(mVars[v].type);
+
+                     newVar = newDeclVar;
+                  }
+                  else
+                  {
+                     Var* newDeclVar = new Var(mVars[v].varName, mVars[v].type);
+
+                     newDeclVar->arraySize = mVars[v].arraySize;
+                     newDeclVar->uniform = mVars[v].uniform;
+                     newDeclVar->sampler = mVars[v].sampler;
+                     newDeclVar->texture = mVars[v].texture;
+                     newDeclVar->constNum = mVars[v].constNum;
+                     newDeclVar->constSortPos = mVars[v].constSortPos;
+
+                     if (!newDeclVar->uniform)
+                     {
+                        LangElement* newVarDecl = new DecOp(newDeclVar);
+                        newVar = (Var*)newVarDecl;
+
+                        declarationStatement = true;
+                     }
+                     else
+                     {
+                        newVar = newDeclVar;
+                     }
+                  }
+               }
+               else
+               {
+                  newVar = getVertTexCoord(mVars[v].varName);
+               }
+
+               mVars.erase(v);
+               break;
+            }
+         }
+
+         if (!newVar)
+         {
+            //couldn't find that variable, bail out
+            Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue());
+            return;
+         }
+      }
+
+      varList.push_back(newVar);
+   }
+
+   //not happy about it, but do a trampoline here to pass along the args
+
+   switch (varList.size())
+   {
+      case 0:
+         meta->addStatement(new GenOp(format + "\n"));
+         break;
+      case 1:
+         meta->addStatement(new GenOp(format + "\n", varList[0]));
+         break;
+      case 2:
+         meta->addStatement(new GenOp(format + "\n", varList[0], varList[1]));
+         break;
+      case 3:
+         meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2]));
+         break;
+      case 4:
+         meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2], varList[3]));
+         break;
+      case 5:
+         meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2], varList[3], varList[4]));
+         break;
+   }
+}
+
+bool CustomFeatureGLSL::hasFeature(String name)
+{
+   for (U32 i = 0; i < mFeatureData.materialFeatures.getCount(); i++)
+   {
+      String featureName = mFeatureData.materialFeatures.getAt(i).getName();
+      if (name == featureName)
+         return true;
+   }
+
+   return false;
+}

+ 132 - 0
Engine/source/shaderGen/GLSL/customFeatureGLSL.h

@@ -0,0 +1,132 @@
+#ifndef _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
+#include "shaderGen/GLSL/shaderFeatureGLSL.h"
+#endif
+#ifndef _LANG_ELEMENT_H_
+#include "shaderGen/langElement.h"
+#endif
+#ifndef _GFXDEVICE_H_
+#include "gfx/gfxDevice.h"
+#endif
+#ifndef _FEATUREMGR_H_
+#include "shaderGen/featureMgr.h"
+#endif
+#ifndef _MATERIALFEATURETYPES_H_
+#include "materials/materialFeatureTypes.h"
+#endif
+#ifndef _MATERIALFEATUREDATA_H_
+#include "materials/materialFeatureData.h"
+#endif
+
+#ifndef CUSTOMSHADERFEATURE_H
+#include "shaderGen/customShaderFeature.h"
+#endif
+
+class CustomShaderFeatureData;
+
+class CustomFeatureGLSL : public ShaderFeatureGLSL
+{
+   friend class CustomShaderFeatureData;
+
+   struct VarHolder
+   {
+      String varName;
+      String type;
+      String defaultValue;
+      S32 elementId;
+      bool uniform;
+      bool sampler;
+      bool texture;
+      bool texCoord;
+      U32 constNum;
+      U32 arraySize;
+      String structName;
+      ConstantSortPosition constSortPos;
+
+      VarHolder() :
+         varName(""),
+         type(""),
+         defaultValue(""),
+         elementId(-1),
+         uniform(false),
+         sampler(false),
+         texture(false),
+         texCoord(false),
+         constNum(0),
+         arraySize(0),
+         structName(""),
+         constSortPos(cspUninit)
+      {
+      }
+
+      VarHolder(String _varName, String _type, String _defaultValue) :
+         elementId(-1), uniform(false), sampler(false), texture(false), texCoord(false), constNum(0), arraySize(0), structName(""), constSortPos(cspUninit)
+      {
+         varName = _varName;
+         type = _type;
+         defaultValue = _defaultValue;
+      }
+   };
+
+   Vector<VarHolder> mVars;
+
+   Vector<VarHolder> mConnectorVars;
+
+   enum outputState
+   {
+      NoOutput,
+      VertexOutput,
+      PixelOutput
+   };
+
+   outputState mOutputState;
+
+public:
+   CustomShaderFeatureData* mOwner;
+
+   Vector<ShaderComponent*> mComponentList;
+   MaterialFeatureData mFeatureData;
+
+protected:
+   MultiLine* meta;
+
+public:
+
+   //****************************************************************************
+   // Accu Texture
+   //****************************************************************************
+   virtual void processVert(Vector<ShaderComponent*>& componentList,
+      const MaterialFeatureData& fd);
+
+   virtual void processPix(Vector<ShaderComponent*>& componentList,
+      const MaterialFeatureData& fd);
+
+   virtual Material::BlendOp getBlendOp() { return Material::LerpAlpha; }
+
+   virtual Resources getResources(const MaterialFeatureData& fd)
+   {
+      Resources res;
+      res.numTex = 1;
+      res.numTexReg = 1;
+      return res;
+   }
+
+   virtual void setTexData(Material::StageData& stageDat,
+      const MaterialFeatureData& fd,
+      RenderPassData& passData,
+      U32& texIndex);
+
+   virtual String getName()
+   {
+      return mOwner->getName();
+   }
+
+   bool hasFeature(String name);
+
+   void addUniform(String name, String type, String defaultValue, U32 arraySize = 0);
+   void addVariable(String name, String type, String defaultValue);
+   void addSampler(String name, String type, U32 arraySize = 0);
+   void addTexture(String name, String type, String samplerState, U32 arraySize);
+   void addConnector(String name, String type, String elementName);
+   void addVertTexCoord(String name);
+   void writeLine(String format, S32 argc, ConsoleValueRef* argv);
+};

+ 424 - 395
Engine/source/shaderGen/HLSL/customFeatureHLSL.cpp

@@ -31,438 +31,467 @@
 //****************************************************************************
 // Accu Texture
 //****************************************************************************
-void CustomFeatureHLSL::processVert(Vector<ShaderComponent*> &componentList,
-	const MaterialFeatureData &fd)
+void CustomFeatureHLSL::processVert(Vector<ShaderComponent*>& componentList,
+   const MaterialFeatureData& fd)
 {
-	/*MultiLine *meta = new MultiLine;
-	getOutTexCoord(   "texCoord",
-	"float2",
-	false,
-	meta,
-	componentList );
+   /*MultiLine *meta = new MultiLine;
+   getOutTexCoord(   "texCoord",
+   "float2",
+   false,
+   meta,
+   componentList );
 
-	getOutObjToTangentSpace( componentList, meta, fd );
+   getOutObjToTangentSpace( componentList, meta, fd );
 
-	output = meta;*/
+   output = meta;*/
 
-	meta = new MultiLine;
+   meta = new MultiLine;
 
-	mFeatureData = fd;
-	mComponentList = componentList;
+   mFeatureData = fd;
+   mComponentList = componentList;
 
-	mOutputState = VertexOutput;
+   mOutputState = VertexOutput;
 
-	if (mOwner->isMethod("processVertHLSL"))
-		Con::executef(mOwner, "processVertHLSL");
+   if (mOwner->isMethod("processVertHLSL"))
+      Con::executef(mOwner, "processVertHLSL");
 
-	output = meta;
+   output = meta;
 }
 
-void CustomFeatureHLSL::processPix(Vector<ShaderComponent*> &componentList,
-	const MaterialFeatureData &fd)
+void CustomFeatureHLSL::processPix(Vector<ShaderComponent*>& componentList,
+   const MaterialFeatureData& fd)
 {
-	meta = new MultiLine;
-
-	mFeatureData = fd;
-	mComponentList = componentList;
-
-	mOutputState = PixelOutput;
-	
-	/*MultiLine *meta = new MultiLine;
-
-	output = meta;
-
-	// OUT.col
-	Var *color = (Var*) LangElement::find( "col1" );
-	if (!color)
-	{
-	output = new GenOp("   //NULL COLOR!");
-	return;
-	}
-
-	// accu map
-	Var *accuMap = new Var;
-	accuMap->setType("SamplerState");
-
-	accuMap->setName( "accuMap" );
-	accuMap->uniform = true;
-	accuMap->sampler = true;
-	accuMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
-
-	// accuColor var
-	Var *accuColor = new Var;
-	accuColor->setType( "float4" );
-	accuColor->setName( "accuColor" );
-	LangElement *colorAccuDecl = new DecOp( accuColor );
-
-	// plc (placement)
-	Var *accuPlc = new Var;
-	accuPlc->setType( "float4" );
-	accuPlc->setName( "plc" );
-	LangElement *plcAccu = new DecOp( accuPlc );
-
-	// accu constants
-	Var *accuScale = (Var*)LangElement::find( "accuScale" );
-	if ( !accuScale )
-	{
-	accuScale = new Var;
-	accuScale->setType( "float" );
-	accuScale->setName( "accuScale" );
-	accuScale->uniform = true;
-	accuScale->sampler = false;
-	accuScale->constSortPos = cspPotentialPrimitive;
-	}
-	Var *accuDirection = (Var*)LangElement::find( "accuDirection" );
-	if ( !accuDirection )
-	{
-	accuDirection = new Var;
-	accuDirection->setType( "float" );
-	accuDirection->setName( "accuDirection" );
-	accuDirection->uniform = true;
-	accuDirection->sampler = false;
-	accuDirection->constSortPos = cspPotentialPrimitive;
-	}
-	Var *accuStrength = (Var*)LangElement::find( "accuStrength" );
-	if ( !accuStrength )
-	{
-	accuStrength = new Var;
-	accuStrength->setType( "float" );
-	accuStrength->setName( "accuStrength" );
-	accuStrength->uniform = true;
-	accuStrength->sampler = false;
-	accuStrength->constSortPos = cspPotentialPrimitive;
-	}
-	Var *accuCoverage = (Var*)LangElement::find( "accuCoverage" );
-	if ( !accuCoverage )
-	{
-	accuCoverage = new Var;
-	accuCoverage->setType( "float" );
-	accuCoverage->setName( "accuCoverage" );
-	accuCoverage->uniform = true;
-	accuCoverage->sampler = false;
-	accuCoverage->constSortPos = cspPotentialPrimitive;
-	}
-	Var *accuSpecular = (Var*)LangElement::find( "accuSpecular" );
-	if ( !accuSpecular )
-	{
-	accuSpecular = new Var;
-	accuSpecular->setType( "float" );
-	accuSpecular->setName( "accuSpecular" );
-	accuSpecular->uniform = true;
-	accuSpecular->sampler = false;
-	accuSpecular->constSortPos = cspPotentialPrimitive;
-	}
-
-	Var *inTex = getInTexCoord( "texCoord", "float2", componentList );
-	Var *accuVec = getInTexCoord( "accuVec", "float3", componentList );
-	Var *bumpNorm = (Var *)LangElement::find( "bumpSample" );
-	if( bumpNorm == NULL )
-	{
-	bumpNorm = (Var *)LangElement::find( "bumpNormal" );
-	if (!bumpNorm)
-	return;
-	}
-
-	// get the accu pixel color
-
-	Var *accuMapTex = new Var;
-	accuMapTex->setType("Texture2D");
-	accuMapTex->setName("accuMapTex");
-	accuMapTex->uniform = true;
-	accuMapTex->texture = true;
-	accuMapTex->constNum = accuMap->constNum;
-	meta->addStatement(new GenOp("   @ = @.Sample(@, @ * @);\r\n", colorAccuDecl, accuMapTex, accuMap, inTex, accuScale));
-
-	// scale up normals
-	meta->addStatement( new GenOp( "   @.xyz = @.xyz * 2.0 - 0.5;\r\n", bumpNorm, bumpNorm ) );
-
-	// assign direction
-	meta->addStatement( new GenOp( "   @.z *= @*2.0;\r\n", accuVec, accuDirection ) );
-
-	// saturate based on strength
-	meta->addStatement( new GenOp( "   @ = saturate( dot( @.xyz, @.xyz * pow(@, 5) ) );\r\n", plcAccu, bumpNorm, accuVec, accuStrength ) );
-
-	// add coverage
-	meta->addStatement( new GenOp( "   @.a += (2 * pow(@/2, 5)) - 0.5;\r\n", accuPlc, accuCoverage ) );
-
-	// clamp to a sensible value
-	meta->addStatement( new GenOp( "   @.a = clamp(@.a, 0, 1);\r\n", accuPlc, accuPlc ) );
-
-	// light
-	Var *lightColor = (Var*) LangElement::find( "d_lightcolor" );
-	if(lightColor != NULL)
-	meta->addStatement( new GenOp( "   @ *= float4(@, 1.0);\r\n\r\n", accuColor, lightColor ) );
-
-	// lerp with current pixel - use the accu alpha as well
-	meta->addStatement( new GenOp( "   @ = lerp( @, @, @.a * @.a);\r\n", color, color, accuColor, accuPlc, accuColor ) );
-
-	// the result should always be opaque
-	meta->addStatement( new GenOp( "   @.a = 1.0;\r\n", color ) );*/
-	if (mOwner->isMethod("processPixelHLSL"))
-		Con::executef(mOwner, "processPixelHLSL");
-
-	output = meta;
+   meta = new MultiLine;
+
+   mFeatureData = fd;
+   mComponentList = componentList;
+
+   mOutputState = PixelOutput;
+
+   /*MultiLine *meta = new MultiLine;
+
+   output = meta;
+
+   // OUT.col
+   Var *color = (Var*) LangElement::find( "col1" );
+   if (!color)
+   {
+   output = new GenOp("   //NULL COLOR!");
+   return;
+   }
+
+   // accu map
+   Var *accuMap = new Var;
+   accuMap->setType("SamplerState");
+
+   accuMap->setName( "accuMap" );
+   accuMap->uniform = true;
+   accuMap->sampler = true;
+   accuMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
+
+   // accuColor var
+   Var *accuColor = new Var;
+   accuColor->setType( "float4" );
+   accuColor->setName( "accuColor" );
+   LangElement *colorAccuDecl = new DecOp( accuColor );
+
+   // plc (placement)
+   Var *accuPlc = new Var;
+   accuPlc->setType( "float4" );
+   accuPlc->setName( "plc" );
+   LangElement *plcAccu = new DecOp( accuPlc );
+
+   // accu constants
+   Var *accuScale = (Var*)LangElement::find( "accuScale" );
+   if ( !accuScale )
+   {
+   accuScale = new Var;
+   accuScale->setType( "float" );
+   accuScale->setName( "accuScale" );
+   accuScale->uniform = true;
+   accuScale->sampler = false;
+   accuScale->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuDirection = (Var*)LangElement::find( "accuDirection" );
+   if ( !accuDirection )
+   {
+   accuDirection = new Var;
+   accuDirection->setType( "float" );
+   accuDirection->setName( "accuDirection" );
+   accuDirection->uniform = true;
+   accuDirection->sampler = false;
+   accuDirection->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuStrength = (Var*)LangElement::find( "accuStrength" );
+   if ( !accuStrength )
+   {
+   accuStrength = new Var;
+   accuStrength->setType( "float" );
+   accuStrength->setName( "accuStrength" );
+   accuStrength->uniform = true;
+   accuStrength->sampler = false;
+   accuStrength->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuCoverage = (Var*)LangElement::find( "accuCoverage" );
+   if ( !accuCoverage )
+   {
+   accuCoverage = new Var;
+   accuCoverage->setType( "float" );
+   accuCoverage->setName( "accuCoverage" );
+   accuCoverage->uniform = true;
+   accuCoverage->sampler = false;
+   accuCoverage->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuSpecular = (Var*)LangElement::find( "accuSpecular" );
+   if ( !accuSpecular )
+   {
+   accuSpecular = new Var;
+   accuSpecular->setType( "float" );
+   accuSpecular->setName( "accuSpecular" );
+   accuSpecular->uniform = true;
+   accuSpecular->sampler = false;
+   accuSpecular->constSortPos = cspPotentialPrimitive;
+   }
+
+   Var *inTex = getInTexCoord( "texCoord", "float2", componentList );
+   Var *accuVec = getInTexCoord( "accuVec", "float3", componentList );
+   Var *bumpNorm = (Var *)LangElement::find( "bumpSample" );
+   if( bumpNorm == NULL )
+   {
+   bumpNorm = (Var *)LangElement::find( "bumpNormal" );
+   if (!bumpNorm)
+   return;
+   }
+
+   // get the accu pixel color
+
+   Var *accuMapTex = new Var;
+   accuMapTex->setType("Texture2D");
+   accuMapTex->setName("accuMapTex");
+   accuMapTex->uniform = true;
+   accuMapTex->texture = true;
+   accuMapTex->constNum = accuMap->constNum;
+   meta->addStatement(new GenOp("   @ = @.Sample(@, @ * @);\r\n", colorAccuDecl, accuMapTex, accuMap, inTex, accuScale));
+
+   // scale up normals
+   meta->addStatement( new GenOp( "   @.xyz = @.xyz * 2.0 - 0.5;\r\n", bumpNorm, bumpNorm ) );
+
+   // assign direction
+   meta->addStatement( new GenOp( "   @.z *= @*2.0;\r\n", accuVec, accuDirection ) );
+
+   // saturate based on strength
+   meta->addStatement( new GenOp( "   @ = saturate( dot( @.xyz, @.xyz * pow(@, 5) ) );\r\n", plcAccu, bumpNorm, accuVec, accuStrength ) );
+
+   // add coverage
+   meta->addStatement( new GenOp( "   @.a += (2 * pow(@/2, 5)) - 0.5;\r\n", accuPlc, accuCoverage ) );
+
+   // clamp to a sensible value
+   meta->addStatement( new GenOp( "   @.a = clamp(@.a, 0, 1);\r\n", accuPlc, accuPlc ) );
+
+   // light
+   Var *lightColor = (Var*) LangElement::find( "d_lightcolor" );
+   if(lightColor != NULL)
+   meta->addStatement( new GenOp( "   @ *= float4(@, 1.0);\r\n\r\n", accuColor, lightColor ) );
+
+   // lerp with current pixel - use the accu alpha as well
+   meta->addStatement( new GenOp( "   @ = lerp( @, @, @.a * @.a);\r\n", color, color, accuColor, accuPlc, accuColor ) );
+
+   // the result should always be opaque
+   meta->addStatement( new GenOp( "   @.a = 1.0;\r\n", color ) );*/
+   if (mOwner->isMethod("processPixelHLSL"))
+      Con::executef(mOwner, "processPixelHLSL");
+
+   output = meta;
 }
 
-void CustomFeatureHLSL::setTexData(Material::StageData &stageDat,
-	const MaterialFeatureData &fd,
-	RenderPassData &passData,
-	U32 &texIndex)
+void CustomFeatureHLSL::setTexData(Material::StageData& stageDat,
+   const MaterialFeatureData& fd,
+   RenderPassData& passData,
+   U32& texIndex)
 {
-	//GFXTextureObject *tex = stageDat.getTex( MFT_AccuMap );
-	//if ( tex )
-	//{
-	//passData.mSamplerNames[ texIndex ] = "AccuMap";
-	//passData.mTexType[ texIndex++ ] = Material::AccuMap;
-	//}
-
-	if (mOwner->isMethod("setTextureData"))
-		Con::executef(mOwner, "setTextureData");
+   //GFXTextureObject *tex = stageDat.getTex( MFT_AccuMap );
+   //if ( tex )
+   //{
+   //passData.mSamplerNames[ texIndex ] = "AccuMap";
+   //passData.mTexType[ texIndex++ ] = Material::AccuMap;
+   //}
+
+   if (mOwner->isMethod("setTextureData"))
+      Con::executef(mOwner, "setTextureData");
 }
 
 void CustomFeatureHLSL::addUniform(String name, String type, String defaultValue, U32 arraySize)
 {
-	//do the var/arg fetching here
-	Var *newVar = (Var*)LangElement::find(name.c_str());
-	if (!newVar)
-	{
-		VarHolder newVarHolder(name, type, "");
-		newVarHolder.arraySize = arraySize;
-		newVarHolder.sampler = false;
-		newVarHolder.uniform = true;
-		newVarHolder.constSortPos = cspPotentialPrimitive;
-
-		mVars.push_back(newVarHolder);
-
-		mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str()));
-	}
+   //do the var/arg fetching here
+   Var* newVar = (Var*)LangElement::find(name.c_str());
+   if (!newVar)
+   {
+      VarHolder newVarHolder(name, type, "");
+      newVarHolder.arraySize = arraySize;
+      newVarHolder.sampler = false;
+      newVarHolder.uniform = true;
+      newVarHolder.constSortPos = cspPotentialPrimitive;
+
+      mVars.push_back(newVarHolder);
+
+      mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str()));
+   }
 }
 
 void CustomFeatureHLSL::addSampler(String name, String type, U32 arraySize)
 {
-	//do the var/arg fetching here
-	Var *newVar = (Var*)LangElement::find(name.c_str());
-	if (!newVar)
-	{
-		//As far as I know, it's always SamplerState regardless of the texture's type
-		VarHolder newVarHolder(name, "SamplerState", "");
-		newVarHolder.arraySize = arraySize;
-		newVarHolder.sampler = true;
-		newVarHolder.uniform = true;
-		newVarHolder.constNum = Var::getTexUnitNum();     // used as texture unit num here
-
-		mVars.push_back(newVarHolder);
-
-		mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str()));
-	}
+   //do the var/arg fetching here
+   Var* newVar = (Var*)LangElement::find(name.c_str());
+   if (!newVar)
+   {
+      //As far as I know, it's always SamplerState regardless of the texture's type
+      VarHolder newVarHolder(name, "SamplerState", "");
+      newVarHolder.arraySize = arraySize;
+      newVarHolder.sampler = true;
+      newVarHolder.uniform = true;
+      newVarHolder.constNum = Var::getTexUnitNum();     // used as texture unit num here
+
+      mVars.push_back(newVarHolder);
+
+      mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str()));
+   }
 }
 
 void CustomFeatureHLSL::addTexture(String name, String type, String samplerState, U32 arraySize)
 {
-	//do the var/arg fetching here
-	Var *newVar = (Var*)LangElement::find(name.c_str());
-	if (!newVar)
-	{
-		//go find our sampler state var
-		U32 constNum = 0;
-
-		Var *samplerStateVar = (Var*)LangElement::find(samplerState.c_str());
-		if (!samplerStateVar)
-		{
-			//check our holder vars
-			bool foundHolder = false;
-			for (U32 v = 0; v < mVars.size(); v++)
-			{
-				if (mVars[v].varName == samplerState)
-				{
-					constNum = mVars[v].constNum;
-					foundHolder = true;
-					break;
-				}
-			}
-
-			if (!foundHolder)
-			{
-				Con::errorf("CustomShaderFeature::addTexture: Unable to find texture's sampler state!");
-				return;
-			}
-		}
-		else
-		{
-			constNum = samplerStateVar->constNum;
-		}
-
-		VarHolder newVarHolder(name, type, "");
-		newVarHolder.arraySize = arraySize;
-		newVarHolder.texture = true;
-		newVarHolder.uniform = true;
-		newVarHolder.constNum = constNum;     // used as texture unit num here
-
-		mVars.push_back(newVarHolder);
-
-		mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str()));
-	}
+   //do the var/arg fetching here
+   Var* newVar = (Var*)LangElement::find(name.c_str());
+   if (!newVar)
+   {
+      //go find our sampler state var
+      U32 constNum = 0;
+
+      Var* samplerStateVar = (Var*)LangElement::find(samplerState.c_str());
+      if (!samplerStateVar)
+      {
+         //check our holder vars
+         bool foundHolder = false;
+         for (U32 v = 0; v < mVars.size(); v++)
+         {
+            if (mVars[v].varName == samplerState)
+            {
+               constNum = mVars[v].constNum;
+               foundHolder = true;
+               break;
+            }
+         }
+
+         if (!foundHolder)
+         {
+            Con::errorf("CustomShaderFeature::addTexture: Unable to find texture's sampler state!");
+            return;
+         }
+      }
+      else
+      {
+         constNum = samplerStateVar->constNum;
+      }
+
+      VarHolder newVarHolder(name, type, "");
+      newVarHolder.arraySize = arraySize;
+      newVarHolder.texture = true;
+      newVarHolder.uniform = true;
+      newVarHolder.constNum = constNum;     // used as texture unit num here
+
+      mVars.push_back(newVarHolder);
+
+      mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str()));
+   }
 }
 
 void CustomFeatureHLSL::addVariable(String name, String type, String defaultValue)
 {
-	//do the var/arg fetching here
-	Var *newVar = (Var*)LangElement::find(name.c_str());
-	if (!newVar)
-	{
-		if (!defaultValue.isEmpty())
-		{
-			char declareStatement[128];
-			dSprintf(declareStatement, 128, "   @ = %s;\n", defaultValue.c_str());
-
-			newVar = new Var(name, type);
-			LangElement *newVarDecl = new DecOp(newVar);
-			meta->addStatement(new GenOp(declareStatement, newVarDecl));
-		}
-		else
-		{
-			VarHolder newVarHolder(name, type, defaultValue);
-
-			mVars.push_back(newVarHolder);
-		}
-	}
+   //do the var/arg fetching here
+   Var* newVar = (Var*)LangElement::find(name.c_str());
+   if (!newVar)
+   {
+      if (!defaultValue.isEmpty())
+      {
+         char declareStatement[128];
+         dSprintf(declareStatement, 128, "   @ = %s;\n", defaultValue.c_str());
+
+         newVar = new Var(name, type);
+         LangElement* newVarDecl = new DecOp(newVar);
+         meta->addStatement(new GenOp(declareStatement, newVarDecl));
+      }
+      else
+      {
+         VarHolder newVarHolder(name, type, defaultValue);
+
+         mVars.push_back(newVarHolder);
+      }
+   }
 }
 
-void CustomFeatureHLSL::addConnector(String name, String elementName, String type)
+void CustomFeatureHLSL::addConnector(String name, String type, String elementName)
 {
-	// grab connector texcoord register
-	ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(mComponentList[C_CONNECTOR]);
-
-	//Get element
-	S32 element = -1;
-
-	if (elementName == String("RT_POSITION"))
-		element = RT_POSITION;
-	else if (elementName == String("RT_NORMAL"))
-		element = RT_NORMAL;
-	else if (elementName == String("RT_BINORMAL"))
-		element = RT_BINORMAL;
-	else if (elementName == String("RT_TANGENT"))
-		element = RT_TANGENT;
-	else if (elementName == String("RT_TANGENTW"))
-		element = RT_TANGENTW;
-	else if (elementName == String("RT_COLOR"))
-		element = RT_COLOR;
-	else if (elementName == String("RT_TEXCOORD"))
-		element = RT_TEXCOORD;
-	else if (elementName == String("RT_VPOS"))
-		element = RT_VPOS;
-	else if (elementName == String("RT_SVPOSITION"))
-		element = RT_SVPOSITION;
-	else if (elementName == String("RT_BLENDINDICES"))
-		element = RT_BLENDINDICES;
-	else if (elementName == String("RT_BLENDWEIGHT"))
-		element = RT_BLENDWEIGHT;
-
-	if (element == -1)
-	{
-		Con::errorf("CustomShaderFeatureHLSL::addConnector - Invalid element type %s", elementName.c_str());
-		return;
-	}
-
-	Var *connector = connectComp->getElement((RegisterType)element);
-	connector->setName(name);
-
-	if (mOutputState == VertexOutput)
-		connector->setStructName("OUT");
-	else if(mOutputState == PixelOutput)
-		connector->setStructName("IN");
-
-	connector->setType(type);
+   // grab connector texcoord register
+   ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(mComponentList[C_CONNECTOR]);
+
+   //Get element
+   S32 element = -1;
+
+   if (elementName == String("RT_POSITION"))
+      element = RT_POSITION;
+   else if (elementName == String("RT_NORMAL"))
+      element = RT_NORMAL;
+   else if (elementName == String("RT_BINORMAL"))
+      element = RT_BINORMAL;
+   else if (elementName == String("RT_TANGENT"))
+      element = RT_TANGENT;
+   else if (elementName == String("RT_TANGENTW"))
+      element = RT_TANGENTW;
+   else if (elementName == String("RT_COLOR"))
+      element = RT_COLOR;
+   else if (elementName == String("RT_TEXCOORD"))
+      element = RT_TEXCOORD;
+   else if (elementName == String("RT_VPOS"))
+      element = RT_VPOS;
+   else if (elementName == String("RT_SVPOSITION"))
+      element = RT_SVPOSITION;
+   else if (elementName == String("RT_BLENDINDICES"))
+      element = RT_BLENDINDICES;
+   else if (elementName == String("RT_BLENDWEIGHT"))
+      element = RT_BLENDWEIGHT;
+
+   if (element == -1)
+   {
+      Con::errorf("CustomShaderFeatureHLSL::addConnector - Invalid element type %s", elementName.c_str());
+      return;
+   }
+
+   VarHolder newVarHolder(name, type, "");
+
+   newVarHolder.elementId = element;
+
+   if (mOutputState == VertexOutput)
+      newVarHolder.structName = "OUT";
+   else if (mOutputState == PixelOutput)
+      newVarHolder.structName = "IN";
+
+   mVars.push_back(newVarHolder);
 }
 
-void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef *argv)
+void CustomFeatureHLSL::addVertTexCoord(String name)
 {
-	//do the var/arg fetching here
-	Vector<Var*> varList;
-	bool declarationStatement = false;
-
-	for (U32 i = 0; i < argc; i++)
-	{
-		String varName = argv[i].getStringValue();
-		Var *newVar = (Var*)LangElement::find(varName.c_str());
-		if (!newVar)
-		{
-			//ok, check our existing var holders, see if we just haven't utilized it yet
-			for (U32 v = 0; v < mVars.size(); v++)
-			{
-				if (mVars[v].varName == varName)
-				{
-					Var* newDeclVar = new Var(mVars[v].varName, mVars[v].type);
-
-					newDeclVar->arraySize = mVars[v].arraySize;
-					newDeclVar->uniform = mVars[v].uniform;
-					newDeclVar->sampler = mVars[v].sampler;
-					newDeclVar->texture = mVars[v].texture;
-					newDeclVar->constNum = mVars[v].constNum;
-					newDeclVar->constSortPos = mVars[v].constSortPos;
-
-					if (!newDeclVar->uniform)
-					{
-						LangElement *newVarDecl = new DecOp(newDeclVar);
-						newVar = (Var*)newVarDecl;
-
-						declarationStatement = true;
-					}
-					else
-					{
-						newVar = newDeclVar;
-					}
-
-					mVars.erase(v);
-					break;
-				}
-			}
-
-			if (!newVar)
-			{
-				//couldn't find that variable, bail out
-				Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue());
-				return;
-			}
-		}
-
-		varList.push_back(newVar);
-	}
-
-	//not happy about it, but do a trampoline here to pass along the args
-
-	switch (varList.size())
-	{
-	case 0:
-		meta->addStatement(new GenOp(format + "\n"));
-		break;
-	case 1:
-		meta->addStatement(new GenOp(format + "\n", varList[0]));
-		break;
-	case 2:
-		meta->addStatement(new GenOp(format + "\n", varList[0], varList[1]));
-		break;
-	case 3:
-		meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2]));
-		break;
-	case 4:
-		meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2], varList[3]));
-		break;
-	case 5:
-		meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2], varList[3], varList[4]));
-		break;
-	}
+   VarHolder newVarHolder(name, "", "");
+   newVarHolder.texCoord = true;
+
+   mVars.push_back(newVarHolder);
+}
+
+void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * argv)
+{
+   //do the var/arg fetching here
+   Vector<Var*> varList;
+   bool declarationStatement = false;
+
+   for (U32 i = 0; i < argc; i++)
+   {
+      String varName = argv[i].getStringValue();
+      Var* newVar = (Var*)LangElement::find(varName.c_str());
+      if (!newVar)
+      {
+         //ok, check our existing var holders, see if we just haven't utilized it yet
+         for (U32 v = 0; v < mVars.size(); v++)
+         {
+            if (mVars[v].varName == varName)
+            {
+               if (!mVars[v].texCoord)
+               {
+                  if (mVars[v].elementId != -1)
+                  {
+                     ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(mComponentList[C_CONNECTOR]);
+                     Var* newDeclVar = connectComp->getElement((RegisterType)mVars[v].elementId);
+                     newDeclVar->setName(mVars[v].varName);
+                     newDeclVar->setStructName(mVars[v].structName);
+                     newDeclVar->setType(mVars[v].type);
+
+                     newVar = newDeclVar;
+                  }
+                  else
+                  {
+                     Var* newDeclVar = new Var(mVars[v].varName, mVars[v].type);
+
+                     newDeclVar->arraySize = mVars[v].arraySize;
+                     newDeclVar->uniform = mVars[v].uniform;
+                     newDeclVar->sampler = mVars[v].sampler;
+                     newDeclVar->texture = mVars[v].texture;
+                     newDeclVar->constNum = mVars[v].constNum;
+                     newDeclVar->constSortPos = mVars[v].constSortPos;
+
+                     if (!newDeclVar->uniform)
+                     {
+                        LangElement* newVarDecl = new DecOp(newDeclVar);
+                        newVar = (Var*)newVarDecl;
+
+                        declarationStatement = true;
+                     }
+                     else
+                     {
+                        newVar = newDeclVar;
+                     }
+                  }
+               }
+               else
+               {
+                  newVar = getVertTexCoord(mVars[v].varName);
+               }
+
+               mVars.erase(v);
+               break;
+            }
+         }
+
+         if (!newVar)
+         {
+            //couldn't find that variable, bail out
+            Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue());
+            return;
+         }
+      }
+
+      varList.push_back(newVar);
+   }
+
+   //not happy about it, but do a trampoline here to pass along the args
+
+   switch (varList.size())
+   {
+      case 0:
+         meta->addStatement(new GenOp(format + "\n"));
+         break;
+      case 1:
+         meta->addStatement(new GenOp(format + "\n", varList[0]));
+         break;
+      case 2:
+         meta->addStatement(new GenOp(format + "\n", varList[0], varList[1]));
+         break;
+      case 3:
+         meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2]));
+         break;
+      case 4:
+         meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2], varList[3]));
+         break;
+      case 5:
+         meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2], varList[3], varList[4]));
+         break;
+   }
 }
 
 bool CustomFeatureHLSL::hasFeature(String name)
 {
-	for (U32 i = 0; i < mFeatureData.materialFeatures.getCount(); i++)
-	{
-		String featureName = mFeatureData.materialFeatures.getAt(i).getName();
-		if (name == featureName)
-			return true;
-	}
-
-	return false;
-}
+   for (U32 i = 0; i < mFeatureData.materialFeatures.getCount(); i++)
+   {
+      String featureName = mFeatureData.materialFeatures.getAt(i).getName();
+      if (name == featureName)
+         return true;
+   }
+
+   return false;
+}

+ 97 - 88
Engine/source/shaderGen/HLSL/customFeatureHLSL.h

@@ -25,99 +25,108 @@ class CustomShaderFeatureData;
 
 class CustomFeatureHLSL : public ShaderFeatureHLSL
 {
-	friend class CustomShaderFeatureData;
-
-	struct VarHolder
-	{
-		String varName;
-		String defaultValue;
-		String type;
-		bool uniform;
-		bool sampler;
-		bool texture;
-		U32 constNum;
-		ConstantSortPosition constSortPos;
-		U32 arraySize;
-
-		VarHolder() :
-			varName(""),
-			type(""),
-			defaultValue(""),
-			uniform(false), 
-			sampler(false), 
-			texture(false),
-			constNum(0), 
-			arraySize(0),
-			constSortPos(cspUninit)
-		{
-		}
-
-		VarHolder(String _varName,String _type, String _defaultValue) :
-			uniform(false), sampler(false), texture(false), constNum(0), arraySize(0), constSortPos(cspUninit)
-		{
-			varName = _varName;
-			type = _type;
-			defaultValue = _defaultValue;
-		}
-	};
-
-	Vector<VarHolder> mVars;
-
-	enum outputState
-	{
-		NoOutput,
-		VertexOutput,
-		PixelOutput
-	};
-
-	outputState mOutputState;
+   friend class CustomShaderFeatureData;
+
+   struct VarHolder
+   {
+      String varName;
+      String type;
+      String defaultValue;
+      S32 elementId;
+      bool uniform;
+      bool sampler;
+      bool texture;
+      bool texCoord;
+      U32 constNum;
+      U32 arraySize;
+      String structName;
+      ConstantSortPosition constSortPos;
+
+      VarHolder() :
+         varName(""),
+         type(""),
+         defaultValue(""),
+         elementId(-1),
+         uniform(false),
+         sampler(false),
+         texture(false),
+         texCoord(false),
+         constNum(0),
+         arraySize(0),
+         structName(""),
+         constSortPos(cspUninit)
+      {
+      }
+
+      VarHolder(String _varName, String _type, String _defaultValue) :
+         elementId(-1), uniform(false), sampler(false), texture(false), texCoord(false), constNum(0), arraySize(0), structName(""), constSortPos(cspUninit)
+      {
+         varName = _varName;
+         type = _type;
+         defaultValue = _defaultValue;
+      }
+   };
+
+   Vector<VarHolder> mVars;
+
+   Vector<VarHolder> mConnectorVars;
+
+   enum outputState
+   {
+      NoOutput,
+      VertexOutput,
+      PixelOutput
+   };
+
+   outputState mOutputState;
 
 public:
-	CustomShaderFeatureData* mOwner;
+   CustomShaderFeatureData* mOwner;
 
-	Vector<ShaderComponent*> mComponentList;
-	MaterialFeatureData mFeatureData;
+   Vector<ShaderComponent*> mComponentList;
+   MaterialFeatureData mFeatureData;
 
 protected:
-	MultiLine *meta;
+   MultiLine* meta;
 
 public:
 
-	//****************************************************************************
-	// Accu Texture
-	//****************************************************************************
-	virtual void processVert(Vector<ShaderComponent*> &componentList,
-		const MaterialFeatureData &fd);
-
-	virtual void processPix(Vector<ShaderComponent*> &componentList,
-		const MaterialFeatureData &fd);
-
-	virtual Material::BlendOp getBlendOp() { return Material::LerpAlpha; }
-
-	virtual Resources getResources(const MaterialFeatureData &fd)
-	{
-		Resources res;
-		res.numTex = 1;
-		res.numTexReg = 1;
-		return res;
-	}
-
-	virtual void setTexData(Material::StageData &stageDat,
-		const MaterialFeatureData &fd,
-		RenderPassData &passData,
-		U32 &texIndex);
-
-	virtual String getName()
-	{
-		return mOwner->getName();
-	}
-
-	bool hasFeature(String name);
-
-	void addUniform(String name, String type, String defaultValue, U32 arraySize = 0);
-	void addVariable(String name, String type, String defaultValue);
-	void addSampler(String name, String type, U32 arraySize = 0);
-	void addTexture(String name, String type, String samplerState, U32 arraySize);
-	void addConnector(String name, String elementName, String type);
-	void writeLine(String format, S32 argc, ConsoleValueRef *argv);
-};
+   //****************************************************************************
+   // Accu Texture
+   //****************************************************************************
+   virtual void processVert(Vector<ShaderComponent*>& componentList,
+      const MaterialFeatureData& fd);
+
+   virtual void processPix(Vector<ShaderComponent*>& componentList,
+      const MaterialFeatureData& fd);
+
+   virtual Material::BlendOp getBlendOp() { return Material::LerpAlpha; }
+
+   virtual Resources getResources(const MaterialFeatureData& fd)
+   {
+      Resources res;
+      res.numTex = 1;
+      res.numTexReg = 1;
+      return res;
+   }
+
+   virtual void setTexData(Material::StageData& stageDat,
+      const MaterialFeatureData& fd,
+      RenderPassData& passData,
+      U32& texIndex);
+
+   virtual String getName()
+   {
+      return mOwner->getName();
+   }
+
+   bool hasFeature(String name);
+
+   void addUniform(String name, String type, String defaultValue, U32 arraySize = 0);
+   void addVariable(String name, String type, String defaultValue);
+   void addSampler(String name, String type, U32 arraySize = 0);
+   void addTexture(String name, String type, String samplerState, U32 arraySize);
+   void addConnector(String name, String type, String elementName);
+   void addVertTexCoord(String name);
+   void writeLine(String format, S32 argc, ConsoleValueRef* argv);
+};

+ 84 - 73
Engine/source/shaderGen/customShaderFeature.cpp

@@ -22,6 +22,7 @@
 
 #include "shadergen/CustomShaderFeature.h"
 #include "shaderGen/HLSL/customFeatureHLSL.h"
+#include "shaderGen/GLSL/customFeatureGLSL.h"
 
 #include "math/mathIO.h"
 #include "scene/sceneRenderState.h"
@@ -35,17 +36,17 @@
 IMPLEMENT_CONOBJECT(CustomShaderFeatureData);
 
 ConsoleDocClass(CustomShaderFeatureData,
-	"@brief An example scene object which renders using a callback.\n\n"
-	"This class implements a basic SceneObject that can exist in the world at a "
-	"3D position and render itself. Note that CustomShaderFeatureData handles its own "
-	"rendering by submitting itself as an ObjectRenderInst (see "
-	"renderInstance\renderPassmanager.h) along with a delegate for its render() "
-	"function. However, the preffered rendering method in the engine is to submit "
-	"a MeshRenderInst along with a Material, vertex buffer, primitive buffer, and "
-	"transform and allow the RenderMeshMgr handle the actual rendering. You can "
-	"see this implemented in RenderMeshExample.\n\n"
-	"See the C++ code for implementation details.\n\n"
-	"@ingroup Examples\n");
+   "@brief An example scene object which renders using a callback.\n\n"
+   "This class implements a basic SceneObject that can exist in the world at a "
+   "3D position and render itself. Note that CustomShaderFeatureData handles its own "
+   "rendering by submitting itself as an ObjectRenderInst (see "
+   "renderInstance\renderPassmanager.h) along with a delegate for its render() "
+   "function. However, the preffered rendering method in the engine is to submit "
+   "a MeshRenderInst along with a Material, vertex buffer, primitive buffer, and "
+   "transform and allow the RenderMeshMgr handle the actual rendering. You can "
+   "see this implemented in RenderMeshExample.\n\n"
+   "See the C++ code for implementation details.\n\n"
+   "@ingroup Examples\n");
 
 //-----------------------------------------------------------------------------
 // Object setup and teardown
@@ -63,128 +64,138 @@ CustomShaderFeatureData::~CustomShaderFeatureData()
 //-----------------------------------------------------------------------------
 void CustomShaderFeatureData::initPersistFields()
 {
-	// SceneObject already handles exposing the transform
-	Parent::initPersistFields();
+   // SceneObject already handles exposing the transform
+   Parent::initPersistFields();
 }
 
 bool CustomShaderFeatureData::onAdd()
 {
-	if (!Parent::onAdd())
-		return false;
+   if (!Parent::onAdd())
+      return false;
 
-	mFeatureHLSL = new CustomFeatureHLSL();
-	mFeatureHLSL->mOwner = this;
+   if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+   {
+      mFeatureHLSL = new CustomFeatureHLSL();
+      mFeatureHLSL->mOwner = this;
+   }
+   else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+   {
+      mFeatureGLSL = new CustomFeatureGLSL();
+      mFeatureGLSL->mOwner = this;
+   }
 
-	return true;
+   return true;
 }
 
 void CustomShaderFeatureData::onRemove()
 {
-	Parent::onRemove();
+   Parent::onRemove();
 }
 
 //Shadergen setup functions
 void CustomShaderFeatureData::addVariable(String name, String type, String defaultValue)
 {
-	mFeatureHLSL->addVariable(name, type, defaultValue);
+   if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+      mFeatureHLSL->addVariable(name, type, defaultValue);
+   else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+      mFeatureGLSL->addVariable(name, type, defaultValue);
 }
 
 void CustomShaderFeatureData::addUniform(String name, String type, String defaultValue, U32 arraySize)
 {
-	mFeatureHLSL->addUniform(name, type, defaultValue, arraySize);
+   if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+      mFeatureHLSL->addUniform(name, type, defaultValue, arraySize);
+   else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+      mFeatureGLSL->addUniform(name, type, defaultValue, arraySize);
 }
 
 void CustomShaderFeatureData::addSampler(String name, String type, U32 arraySize)
 {
-	mFeatureHLSL->addSampler(name, type, arraySize);
+   if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+      mFeatureHLSL->addSampler(name, type, arraySize);
+   else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+      mFeatureGLSL->addSampler(name, type, arraySize);
 }
 
 void CustomShaderFeatureData::addTexture(String name, String type, String samplerState, U32 arraySize)
 {
-	mFeatureHLSL->addTexture(name, type, samplerState, arraySize);
+   if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+      mFeatureHLSL->addTexture(name, type, samplerState, arraySize);
+   else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+      mFeatureGLSL->addTexture(name, type, samplerState, arraySize);
 }
 
-void CustomShaderFeatureData::addConnector(String name, String elementName, String type)
+void CustomShaderFeatureData::addConnector(String name, String type, String elementName)
 {
-	mFeatureHLSL->addConnector(name, elementName, type);
+   if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+      mFeatureHLSL->addConnector(name, type, elementName);
+   else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+      mFeatureGLSL->addConnector(name, type, elementName);
 }
 
-bool CustomShaderFeatureData::hasFeature(String name)
+void CustomShaderFeatureData::addVertTexCoord(String name)
 {
-	return mFeatureHLSL->hasFeature(name);
+   if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+      mFeatureHLSL->addVertTexCoord(name);
+   else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+      mFeatureGLSL->addVertTexCoord(name);
 }
 
-void CustomShaderFeatureData::writeLine(String format, S32 argc, ConsoleValueRef *argv)
+bool CustomShaderFeatureData::hasFeature(String name)
 {
-	/*mOnObject = onObject;
-	mArgc = argc;
-
-	mArgv = new ConsoleValueRef[argc];
-	for (int i = 0; i<argc; i++)
-	{
-		mArgv[i].value = new ConsoleValue();
-		mArgv[i].value->type = ConsoleValue::TypeInternalString;
-		mArgv[i].value->init();
-		if (argv)
-		{
-			mArgv[i].value->setStringValue((const char*)argv[i]);
-		}
-	}*/
-
-	mFeatureHLSL->writeLine(format, argc, argv);
+   if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+      return mFeatureHLSL->hasFeature(name);
+   else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+      return mFeatureGLSL->hasFeature(name);
 }
 
-/*//Actual shader processing
-void CustomShaderFeatureData::processVert(Vector<ShaderComponent*> &componentList,
-	const MaterialFeatureData &fd)
+void CustomShaderFeatureData::writeLine(String format, S32 argc, ConsoleValueRef* argv)
 {
-	mFeatureHLSL.processVert(componentList, fd);
+   if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+      mFeatureHLSL->writeLine(format, argc, argv);
+   else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+      mFeatureGLSL->writeLine(format, argc, argv);
 }
 
-void CustomShaderFeatureData::processPix(Vector<ShaderComponent*> &componentList,
-	const MaterialFeatureData &fd)
+DefineEngineMethod(CustomShaderFeatureData, addVariable, void, (String name, String type, String defaultValue), ("", "", ""), "")
 {
-	mFeatureHLSL.processPix(componentList, fd);
-
+   object->addVariable(name, type, defaultValue);
 }
 
-void CustomShaderFeatureData::setTexData(Material::StageData &stageDat,
-	const MaterialFeatureData &fd,
-	RenderPassData &passData,
-	U32 &texIndex)
+DefineEngineMethod(CustomShaderFeatureData, addUniform, void, (String name, String type, String defaultValue, U32 arraySize), ("", "", "", 0), "")
 {
-	mFeatureHLSL.setTexData(stageDat, fd, passData, texIndex);
-}*/
+   object->addUniform(name, type, defaultValue, arraySize);
+}
 
-DefineEngineMethod(CustomShaderFeatureData, addVariable, void, (String name, String type, String defaultValue), ("", "", ""),	"")
+DefineEngineMethod(CustomShaderFeatureData, addSampler, void, (String name, U32 arraySize), ("", 0), "")
 {
-	object->addVariable(name, type, defaultValue);
+   object->addSampler(name, "", arraySize);
 }
 
-DefineEngineMethod(CustomShaderFeatureData, addUniform, void, (String name, String type, String defaultValue, U32 arraySize), ("", "", "", 0), "")
+DefineEngineMethod(CustomShaderFeatureData, addTexture, void, (String name, String type, String samplerState, U32 arraySize), ("", "", 0), "")
 {
-	object->addUniform(name, type, defaultValue, arraySize);
+   object->addTexture(name, type, samplerState, arraySize);
 }
 
-DefineEngineMethod(CustomShaderFeatureData, addSampler, void, (String name, U32 arraySize), ("", 0), "")
+DefineEngineMethod(CustomShaderFeatureData, addConnector, void, (String name, String type, String elementName), ("", "", ""), "")
 {
-	object->addSampler(name, "", arraySize);
+   object->addConnector(name, type, elementName);
 }
 
-DefineEngineMethod(CustomShaderFeatureData, addTexture, void, (String name, String type, String samplerState, U32 arraySize), ("", "", 0), "")
+DefineEngineMethod(CustomShaderFeatureData, addVertTexCoord, void, (String name), (""), "")
 {
-	object->addTexture(name, type, samplerState, arraySize);
+   object->addVertTexCoord(name);
 }
 
-ConsoleMethod(CustomShaderFeatureData, writeLine, void, 3, 0, "( string format, string args... ) Dynamically call a method on an object.\n"
-	"@param method Name of method to call.\n"
-	"@param args Zero or more arguments for the method.\n"
-	"@return The result of the method call.")
+DefineEngineStringlyVariadicMethod(CustomShaderFeatureData, writeLine, void, 3, 0, "( string format, string args... ) Dynamically call a method on an object.\n"
+   "@param method Name of method to call.\n"
+   "@param args Zero or more arguments for the method.\n"
+   "@return The result of the method call.")
 {
-	object->writeLine(argv[2], argc - 3, argv + 3);
+   object->writeLine(argv[2], argc - 3, argv + 3);
 }
 
 DefineEngineMethod(CustomShaderFeatureData, hasFeature, bool, (String name), (""), "")
 {
-	return object->hasFeature(name);
-}
+   return object->hasFeature(name);
+}

+ 5 - 3
Engine/source/shaderGen/customShaderFeature.h

@@ -28,6 +28,7 @@
 #endif
 
 class CustomFeatureHLSL;
+class CustomFeatureGLSL;
 
 class CustomShaderFeatureData : public SimObject
 {
@@ -35,6 +36,7 @@ class CustomShaderFeatureData : public SimObject
 
 public:
 	CustomFeatureHLSL* mFeatureHLSL;
+   CustomFeatureGLSL* mFeatureGLSL;
 
 	Vector<StringTableEntry> mAddedShaderConstants;
 
@@ -64,8 +66,8 @@ public:
 	void addUniform(String name, String type, String defaultValue, U32 arraySize);
 	void addSampler(String name, String type, U32 arraySize);
 	void addTexture(String name, String type, String samplerState, U32 arraySize);
-	void addConnector(String name, String elementName, String type);
-
+	void addConnector(String name, String type, String elementName);
+   void addVertTexCoord(String name);
 	bool hasFeature(String name);
 
 	void writeLine(String format, S32 argc, ConsoleValueRef *argv);
@@ -81,4 +83,4 @@ public:
 		U32 &texIndex);*/
 };
 
-#endif
+#endif

+ 43 - 24
Engine/source/shaderGen/shaderGen.cpp

@@ -32,6 +32,7 @@
 #include "core/module.h"
 
 #include "shaderGen/HLSL/customFeatureHLSL.h"
+#include "shaderGen/GLSL/customFeatureGLSL.h"
 
 MODULE_BEGIN( ShaderGen )
 
@@ -290,23 +291,32 @@ void ShaderGen::_processVertFeatures( Vector<GFXShaderMacro> &macros, bool macro
    {
 	   for (U32 i = 0; i < mCustomFeaturesData.size(); ++i)
 	   {
-		   mCustomFeaturesData[i]->mFeatureHLSL->processVert(mComponents, mFeatureData);
+         if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+         {
+            mCustomFeaturesData[i]->mFeatureHLSL->processVert(mComponents, mFeatureData);
 
-		   String line = String::ToString("   // %s\r\n", mCustomFeaturesData[i]->mFeatureHLSL->getName().c_str());
-		   mOutput->addStatement(new GenOp(line));
+            String line = String::ToString("   // %s\r\n", mCustomFeaturesData[i]->mFeatureHLSL->getName().c_str());
+            mOutput->addStatement(new GenOp(line));
 
-		   if (mCustomFeaturesData[i]->mFeatureHLSL->getOutput())
-			   mOutput->addStatement(mCustomFeaturesData[i]->mFeatureHLSL->getOutput());
-		   //ShaderFeatureHLSL feature = mCustomFeaturesData[i]->mHLSLFeature;
-		   //feature->setProcessIndex(index);
+            if (mCustomFeaturesData[i]->mFeatureHLSL->getOutput())
+               mOutput->addStatement(mCustomFeaturesData[i]->mFeatureHLSL->getOutput());
 
-		   /*feature->processPixMacros(macros, mFeatureData);
+            mCustomFeaturesData[i]->mFeatureHLSL->reset();
+            mOutput->addStatement(new GenOp("   \r\n"));
+         }
+         else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+         {
+            mCustomFeaturesData[i]->mFeatureGLSL->processVert(mComponents, mFeatureData);
 
-		   feature->setInstancingFormat(&mInstancingFormat);
-		   feature->processPix(mComponents, mFeatureData);*/
+            String line = String::ToString("   // %s\r\n", mCustomFeaturesData[i]->mFeatureGLSL->getName().c_str());
+            mOutput->addStatement(new GenOp(line));
 
-		   mCustomFeaturesData[i]->mFeatureHLSL->reset();
-		   mOutput->addStatement(new GenOp("   \r\n"));
+            if (mCustomFeaturesData[i]->mFeatureGLSL->getOutput())
+               mOutput->addStatement(mCustomFeaturesData[i]->mFeatureGLSL->getOutput());
+
+            mCustomFeaturesData[i]->mFeatureGLSL->reset();
+            mOutput->addStatement(new GenOp("   \r\n"));
+         }
 	   }
    }
 
@@ -355,23 +365,32 @@ void ShaderGen::_processPixFeatures( Vector<GFXShaderMacro> &macros, bool macros
    {
 	   for (U32 i = 0; i < mCustomFeaturesData.size(); ++i)
 	   {
-		   mCustomFeaturesData[i]->mFeatureHLSL->processPix(mComponents, mFeatureData);
+         if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
+         {
+            mCustomFeaturesData[i]->mFeatureHLSL->processPix(mComponents, mFeatureData);
 
-		   String line = String::ToString("   // %s\r\n", mCustomFeaturesData[i]->mFeatureHLSL->getName().c_str());
-		   mOutput->addStatement(new GenOp(line));
+            String line = String::ToString("   // %s\r\n", mCustomFeaturesData[i]->mFeatureHLSL->getName().c_str());
+            mOutput->addStatement(new GenOp(line));
 
-		   if (mCustomFeaturesData[i]->mFeatureHLSL->getOutput())
-			   mOutput->addStatement(mCustomFeaturesData[i]->mFeatureHLSL->getOutput());
-		   //ShaderFeatureHLSL feature = mCustomFeaturesData[i]->mHLSLFeature;
-		   //feature->setProcessIndex(index);
+            if (mCustomFeaturesData[i]->mFeatureHLSL->getOutput())
+               mOutput->addStatement(mCustomFeaturesData[i]->mFeatureHLSL->getOutput());
 
-		   /*feature->processPixMacros(macros, mFeatureData);
+            mCustomFeaturesData[i]->mFeatureHLSL->reset();
+            mOutput->addStatement(new GenOp("   \r\n"));
+         }
+         else if (GFX->getAdapterType() == GFXAdapterType::OpenGL)
+         {
+            mCustomFeaturesData[i]->mFeatureGLSL->processPix(mComponents, mFeatureData);
 
-		   feature->setInstancingFormat(&mInstancingFormat);
-		   feature->processPix(mComponents, mFeatureData);*/
+            String line = String::ToString("   // %s\r\n", mCustomFeaturesData[i]->mFeatureGLSL->getName().c_str());
+            mOutput->addStatement(new GenOp(line));
 
-		   mCustomFeaturesData[i]->mFeatureHLSL->reset();
-		   mOutput->addStatement(new GenOp("   \r\n"));
+            if (mCustomFeaturesData[i]->mFeatureGLSL->getOutput())
+               mOutput->addStatement(mCustomFeaturesData[i]->mFeatureGLSL->getOutput());
+
+            mCustomFeaturesData[i]->mFeatureGLSL->reset();
+            mOutput->addStatement(new GenOp("   \r\n"));
+         }
 	   }
    }
    

+ 207 - 0
Templates/BaseGame/game/tools/MainEditor/MainEditor.cs

@@ -0,0 +1,207 @@
+function MainEditor::onCreate( %this )
+{
+   echo("\n--------- Initializing MainEditor ---------");
+   
+   //exec("tools/gui/profiles.ed.cs");
+   //exec("./scripts/GuiProfiles.cs");
+
+   exec("./guis/MainEditorWindow.gui");
+   
+   //exec("./scripts/newEditorGui.cs");
+   
+   $UsePanelLayout = false;
+   $AssetBrowserPanelState = true;
+   $AssetBrowserPanelSplit = 0;
+   $InspectorPanelState = true;
+   $InspectorPanelSplit = 0;
+   $ToolsPanelState = true;
+   $ToolsPanelSplit = 0;
+}
+
+function MainEditor::onDestroy( %this )
+{
+}
+
+function NewEditorGui::addNewEditorTab(%this, %editorName)
+{
+   %editorTab = new GuiTabPageCtrl()
+   {
+      Profile = "ToolsGuiEditorTabPage";
+      position = "0 0";
+      extent = Editor_MainViewTabBook.extent;
+      AnchorTop = "1";
+      AnchorBottom = "0";
+      AnchorLeft = "1";
+      AnchorRight = "0";
+      horizSizing = "width";
+      vertSizing = "height";
+      text = %editorName;
+   };
+   
+   Editor_MainViewTabBook.add(%editorTab);
+   
+   return %editorTab;
+}
+
+function togglePanelLayout()
+{
+   $UsePanelLayout = !$UsePanelLayout;
+   
+   if($UsePanelLayout)
+   {
+      EditorGui.add(NewEditorGui);
+      
+      //Nudge us down so we show the toolbar
+      NewEditorGui.resize(0, EditorGuiToolbar.extent.y, EditorGui.extent.x, EditorGui.extent.y - EditorGuiToolbar.extent.y - EditorGuiStatusBar.extent.y);
+      
+      %mainEditViewTitle = "Level - " @ getScene(0).getName();
+      %mainEditViewCtrl = NewEditorGui.addNewEditorTab(%mainEditViewTitle);
+      
+      %mainEditViewCtrl.add(EWorldEditor);
+      EWorldEditor.position = "0 24";
+      EWorldEditor.extent = %mainEditViewCtrl.extent.x SPC %mainEditViewCtrl.extent.y - 24;
+      
+      Editor_AssetBrowserPanel.add(AssetBrowser);
+      AssetBrowser.resize(0,0, Editor_AssetBrowserPanel.extent.x, Editor_AssetBrowserPanel.extent.y);
+      AssetBrowser.horizSizing = "width";
+      AssetBrowser.vertSizing = "height";
+      AssetBrowserWindow.resize(0,0, AssetBrowser.extent.x, AssetBrowser.extent.y);
+      AssetBrowserWindow.horizSizing = "width";
+      AssetBrowserWindow.vertSizing = "height";
+      AssetBrowserWindow.canClose = false;
+      AssetBrowserWindow.canCollapse = false;
+      AssetBrowserWindow.canMaximize = false;
+      AssetBrowserWindow.canMinimize = false;
+      AssetBrowserWindow.canMove = false;
+      AssetBrowserWindow.resizeWidth = false;
+      AssetBrowserWindow.resizeHeight = false;
+      
+      //Prep it
+      AssetBrowser.loadFilters();
+     
+      Editor_SceneTreePanel.add(EWTreeWindow);
+      EWTreeWindow.resize(0,0, Editor_SceneTreePanel.extent.x, Editor_SceneTreePanel.extent.y);
+      EWTreeWindow.horizSizing = "width";
+      EWTreeWindow.vertSizing = "height";
+      EWTreeWindow.canClose = false;
+      EWTreeWindow.canCollapse = false;
+      EWTreeWindow.canMaximize = false;
+      EWTreeWindow.canMinimize = false;
+      EWTreeWindow.canMove = false;
+      EWTreeWindow.resizeWidth = false;
+      EWTreeWindow.resizeHeight = false;
+      
+      if(!isObject(Scenes))
+      {
+         $scenesRootGroup = new SimGroup(Scenes);
+      
+         $scenesRootGroup.add(getScene(0));
+      }
+      
+      EditorTree.open($scenesRootGroup,true);
+      
+      Editor_PropertiesPanel.add(EWInspectorWindow);
+      EWInspectorWindow.resize(0,0, Editor_PropertiesPanel.extent.x, Editor_PropertiesPanel.extent.y);
+      EWInspectorWindow.horizSizing = "width";
+      EWInspectorWindow.vertSizing = "height";
+      EWInspectorWindow.canClose = false;
+      EWInspectorWindow.canCollapse = false;
+      EWInspectorWindow.canMaximize = false;
+      EWInspectorWindow.canMinimize = false;
+      EWInspectorWindow.canMove = false;
+      EWInspectorWindow.resizeWidth = false;
+      EWInspectorWindow.resizeHeight = false;
+   }
+   else
+   {
+      EditorGui.remove(NewEditorGui);
+      
+      EditorGui.add(EWorldEditor);
+      
+      EditorGui.add(AssetBrowser);
+      AssetBrowserWindow.canClose = false;
+      AssetBrowserWindow.canCollapse = false;
+      AssetBrowserWindow.canMaximize = false;
+      AssetBrowserWindow.canMinimize = false;
+      AssetBrowserWindow.canMove = false;
+      
+      EditorGui.add(EWTreeWindow);
+      
+      EditorGui.add(EWInspectorWindow);
+   }
+}
+
+function Editor_AssetBrowserButton::onClick(%this)
+{
+   $AssetBrowserPanelState = !$AssetBrowserPanelState;
+   
+   //If we're collapsing
+   if(!$AssetBrowserPanelState)
+   {
+      //Store the original
+      $AssetBrowserPanelSplit = Editor_MainViewSplit.splitPoint.y;
+      
+      //collapse it
+      Editor_MainViewSplit.setSplitPoint(Editor_MainViewSplit.splitPoint.x SPC  Editor_MainViewSplit.extent.y - Editor_MainViewSplit.splitterSize);
+   }
+   else
+   {
+      //restore the original
+      Editor_MainViewSplit.setSplitPoint(Editor_MainViewSplit.splitPoint.x SPC $AssetBrowserPanelSplit);
+   }
+}
+
+function Editor_InspectorSidebarButton::onClick(%this)
+{
+   $InspectorPanelState = !$InspectorPanelState;
+   
+   //If we're collapsing
+   if(!$InspectorPanelState)
+   {
+      //Store the original
+      $InspectorPanelSplit = NewEditorGuiLayout.splitPoint.x;
+      
+      //collapse it
+      NewEditorGuiLayout.setSplitPoint(NewEditorGui.extent.x - NewEditorGuiLayout.splitterSize SPC NewEditorGuiLayout.splitPoint.y);
+   }
+   else
+   {
+      //restore the original
+      NewEditorGuiLayout.setSplitPoint($InspectorPanelSplit SPC NewEditorGuiLayout.splitPoint.y);
+   }
+}
+
+function Editor_ToolsSidebarButton::onClick(%this)
+{
+   $ToolsPanelState = !$ToolsPanelState;
+   
+   //If we're collapsing
+   if(!$ToolsPanelState)
+   {
+      //Store the original
+      $ToolsPanelSplit = Editor_ToolsMainSplit.splitPoint.x;
+      
+      //collapse it
+      Editor_ToolsMainSplit.setSplitPoint(Editor_ToolsMainSplit.splitterSize SPC Editor_ToolsMainSplit.splitPoint.y);
+   }
+   else
+   {
+      //restore the original
+      Editor_ToolsMainSplit.setSplitPoint($ToolsPanelSplit SPC Editor_ToolsMainSplit.splitPoint.y);
+   }
+}
+
+function Editor_VisibilityOptionsButton::onClick(%this)
+{
+   if ( EVisibility.visible  )
+   {
+      EVisibility.setVisible(false);
+      //visibilityToggleBtn.setStateOn(0);
+   }
+   else
+   {
+      EVisibility.setVisible(true);
+      //visibilityToggleBtn.setStateOn(1);
+      EVisibility.setExtent("200 540");
+   }  
+}

+ 9 - 0
Templates/BaseGame/game/tools/MainEditor/MainEditor.module

@@ -0,0 +1,9 @@
+<ModuleDefinition
+	ModuleId="MainEditor"
+	VersionId="1"
+	Description="Tool that can be used to view/edit an object."
+	ScriptFile="MainEditor.cs"
+	CreateFunction="onCreate"
+	DestroyFunction="onDestroy"
+	Group="Tools">
+</ModuleDefinition>

二进制
Templates/BaseGame/game/tools/MainEditor/art/Button.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/GroupBackground.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/GroupBackground_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/GroupBackground_i.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/PropertyRollout.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/ScrollBar.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/ScrollBar_.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/Spacer.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddEvent.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddEvent_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddEvent_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddGroup.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddGroup_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddGroup_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddL.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddL_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddL_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddR.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddR_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddR_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddSml.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddSml_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddSml_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddTrack.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddTrack_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_AddTrack_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Delete.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_DeleteSml.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_DeleteSml_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_DeleteSml_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Delete_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Delete_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Forward.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Forward_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Forward_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Palette_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Palette_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Palette_n.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Pause.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Pause_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Pause_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Play.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Play_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Play_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Rewind.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Rewind_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_Rewind_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_StepB.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_StepB_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_StepB_h.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_StepF.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_StepF_d.png


二进制
Templates/BaseGame/game/tools/MainEditor/art/btn_StepF_h.png


+ 485 - 0
Templates/BaseGame/game/tools/MainEditor/guis/MainEditorWindow.gui

@@ -0,0 +1,485 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiContainer(NewEditorGui) {
+   margin = "0 0 0 0";
+   padding = "0 0 0 0";
+   anchorTop = "1";
+   anchorBottom = "0";
+   anchorLeft = "1";
+   anchorRight = "0";
+   position = "0 0";
+   extent = "1920 1080";
+   minExtent = "8 8";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "ToolsGuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      enabled = "1";
+
+   new GuiSplitContainer(NewEditorGuiLayout) {
+      orientation = "Vertical";
+      splitterSize = "2";
+      splitPoint = "1661 100";
+      fixedPanel = "None";
+      useMinExtent="0";
+      fixedSize = "260";
+      docking = "None";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "0 0";
+      extent = "1921 1081";
+      minExtent = "64 64";
+      horizSizing = "width";
+      vertSizing = "height";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiPanel() {
+         docking = "Client";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "0 0";
+         extent = "1659 1081";
+         minExtent = "0 0";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "Panel1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiSplitContainer(Editor_ToolsMainSplit) {
+            orientation = "Vertical";
+            splitterSize = "2";
+            splitPoint = "230 100";
+            fixedPanel = "None";
+            useMinExtent="0";
+            fixedSize = "1429";
+            docking = "None";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "0 0";
+            extent = "1659 1081";
+            minExtent = "64 64";
+            horizSizing = "width";
+            vertSizing = "height";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiPanel(Editor_ToolSidebarPanel) {
+               docking = "Client";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "0 0";
+               extent = "228 1081";
+               minExtent = "0 0";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "1";
+               internalName = "Panel1";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+
+               new GuiWindowCtrl(Editor_ToolsSidebarWindow) {
+                  text = "Tool Settings";
+                  resizeWidth = "0";
+                  resizeHeight = "0";
+                  canMove = "0";
+                  canClose = "0";
+                  canMinimize = "0";
+                  canMaximize = "0";
+                  canCollapse = "0";
+                  edgeSnap = "1";
+                  margin = "0 0 0 0";
+                  padding = "0 0 0 0";
+                  anchorTop = "1";
+                  anchorBottom = "0";
+                  anchorLeft = "1";
+                  anchorRight = "0";
+                  position = "0 0";
+                  extent = "228 1081";
+                  minExtent = "8 2";
+                  horizSizing = "width";
+                  vertSizing = "height";
+                  profile = "GuiWindowProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  canSave = "1";
+                  canSaveDynamicFields = "0";
+               };
+            };
+            new GuiPanel(Editor_MainWindowPanel) {
+               docking = "Client";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "232 0";
+               extent = "1427 1081";
+               minExtent = "0 0";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "1";
+               internalName = "panel2";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+
+               new GuiSplitContainer(Editor_MainViewSplit) {
+                  orientation = "Horizontal";
+                  splitterSize = "2";
+                  splitPoint = "182 745";
+                  fixedPanel = "None";
+                  useMinExtent="0";
+                  fixedSize = "273";
+                  docking = "None";
+                  margin = "0 0 0 0";
+                  padding = "0 0 0 0";
+                  anchorTop = "1";
+                  anchorBottom = "0";
+                  anchorLeft = "1";
+                  anchorRight = "0";
+                  position = "0 0";
+                  extent = "1427 1081";
+                  minExtent = "64 64";
+                  horizSizing = "width";
+                  vertSizing = "height";
+                  profile = "GuiDefaultProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  canSave = "1";
+                  canSaveDynamicFields = "0";
+
+                  new GuiPanel(Editor_MainViewPanel) {
+                     docking = "Client";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "0 0";
+                     extent = "1427 743";
+                     minExtent = "0 0";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiDefaultProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "1";
+                     internalName = "Panel1";
+                     canSave = "1";
+                     canSaveDynamicFields = "0";
+
+                     new GuiTabBookCtrl(Editor_MainViewTabBook) {
+                        tabPosition = "Top";
+                        tabMargin = "7";
+                        minTabWidth = "64";
+                        tabHeight = "20";
+                        allowReorder = "0";
+                        defaultPage = "-1";
+                        selectedPage = "-1";
+                        frontTabPadding = "0";
+                        margin = "0 0 0 0";
+                        padding = "0 0 0 0";
+                        anchorTop = "1";
+                        anchorBottom = "0";
+                        anchorLeft = "1";
+                        anchorRight = "0";
+                        position = "0 0";
+                        extent = "1427 743";
+                        minExtent = "8 2";
+                        horizSizing = "width";
+                        vertSizing = "height";
+                        profile = "ToolsGuiTabBookProfile";
+                        visible = "1";
+                        active = "1";
+                        tooltipProfile = "GuiToolTipProfile";
+                        hovertime = "1000";
+                        isContainer = "1";
+                        canSave = "1";
+                        canSaveDynamicFields = "0";
+                     };
+                     new GuiBitmapButtonCtrl(Editor_InspectorSidebarButton) {
+                        bitmap = "tools/gui/images/iconAdd.png";
+                        bitmapMode = "Stretched";
+                        autoFitExtents = "0";
+                        useModifiers = "0";
+                        useStates = "1";
+                        masked = "0";
+                        groupNum = "-1";
+                        buttonType = "PushButton";
+                        useMouseEvents = "0";
+                        position = "1411 61";
+                        extent = "15 15";
+                        minExtent = "8 2";
+                        horizSizing = "left";
+                        vertSizing = "bottom";
+                        profile = "GuiDefaultProfile";
+                        visible = "1";
+                        active = "1";
+                        tooltipProfile = "GuiToolTipProfile";
+                        hovertime = "1000";
+                        isContainer = "0";
+                        canSave = "1";
+                        canSaveDynamicFields = "0";
+                     };
+                     new GuiBitmapButtonCtrl(Editor_ToolsSidebarButton) {
+                        bitmap = "tools/gui/images/iconAdd.png";
+                        bitmapMode = "Stretched";
+                        autoFitExtents = "0";
+                        useModifiers = "0";
+                        useStates = "1";
+                        masked = "0";
+                        groupNum = "-1";
+                        buttonType = "PushButton";
+                        useMouseEvents = "0";
+                        position = "0 61";
+                        extent = "15 15";
+                        minExtent = "8 2";
+                        horizSizing = "right";
+                        vertSizing = "bottom";
+                        profile = "GuiDefaultProfile";
+                        visible = "1";
+                        active = "1";
+                        tooltipProfile = "GuiToolTipProfile";
+                        hovertime = "1000";
+                        isContainer = "0";
+                        canSave = "1";
+                        canSaveDynamicFields = "0";
+                     };
+                     new GuiBitmapButtonCtrl(Editor_AssetBrowserButton) {
+                        bitmap = "tools/gui/images/iconAdd.png";
+                        bitmapMode = "Stretched";
+                        autoFitExtents = "0";
+                        useModifiers = "0";
+                        useStates = "1";
+                        masked = "0";
+                        groupNum = "-1";
+                        buttonType = "PushButton";
+                        useMouseEvents = "0";
+                        position = "1411 725";
+                        extent = "15 15";
+                        minExtent = "8 2";
+                        horizSizing = "left";
+                        vertSizing = "top";
+                        profile = "GuiDefaultProfile";
+                        visible = "1";
+                        active = "1";
+                        tooltipProfile = "GuiToolTipProfile";
+                        hovertime = "1000";
+                        isContainer = "0";
+                        canSave = "1";
+                        canSaveDynamicFields = "0";
+                     };
+                     new GuiBitmapButtonCtrl(Editor_VisibilityOptionsButton) {
+                        bitmap = "tools/gui/images/visible";
+                        bitmapMode = "Stretched";
+                        autoFitExtents = "0";
+                        useModifiers = "0";
+                        useStates = "1";
+                        masked = "0";
+                        groupNum = "-1";
+                        buttonType = "PushButton";
+                        useMouseEvents = "0";
+                        position = "16 30";
+                        extent = "18 18";
+                        minExtent = "8 2";
+                        horizSizing = "right";
+                        vertSizing = "bottom";
+                        profile = "GuiDefaultProfile";
+                        visible = "1";
+                        active = "1";
+                        tooltipProfile = "GuiToolTipProfile";
+                        hovertime = "1000";
+                        isContainer = "0";
+                        canSave = "1";
+                        canSaveDynamicFields = "0";
+                     };
+                  };
+                  new GuiPanel(Editor_AssetBrowserPanel) {
+                     docking = "Client";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "0 747";
+                     extent = "1427 334";
+                     minExtent = "16 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiDefaultProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "1";
+                     internalName = "panel2";
+                     canSave = "1";
+                     canSaveDynamicFields = "0";
+                  };
+               };
+            };
+         };
+      };
+      new GuiPanel(Editor_InspectorPanel) {
+         docking = "Client";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "1663 0";
+         extent = "258 1081";
+         minExtent = "0 0";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "panel2";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiSplitContainer() {
+            orientation = "Horizontal";
+            splitterSize = "2";
+            splitPoint = "182 556";
+            fixedPanel = "None";
+            useMinExtent="0";
+            fixedSize = "100";
+            docking = "None";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "0 0";
+            extent = "258 1081";
+            minExtent = "64 64";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiPanel(Editor_SceneTreePanel) {
+               docking = "Client";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "0 0";
+               extent = "258 554";
+               minExtent = "0 0";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "1";
+               internalName = "Panel1";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiPanel(Editor_PropertiesPanel) {
+               docking = "Client";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "0 558";
+               extent = "258 523";
+               minExtent = "0 0";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "1";
+               internalName = "panel2";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 213 - 0
Templates/BaseGame/game/tools/MainEditor/scripts/GuiProfiles.cs

@@ -0,0 +1,213 @@
+//-----------------------------------------------------------------------------
+// Verve
+// Copyright (C) - Violent Tulip
+//-----------------------------------------------------------------------------
+
+singleton GuiControlProfile( VEditorDefaultProfile )
+{
+    opaque        = true;
+    fillColor     = "70 70 70";
+    fillColorHL   = "90 90 90";
+    fillColorNA   = "70 70 70";
+    
+    border        = 1;
+    borderColor   = "120 120 120";
+    borderColorHL = "100 100 100";
+    borderColorNA = "240 240 240";
+
+    fontType      = "Arial";
+    fontSize      = 12;
+    fontCharset   = ANSI;
+
+    fontColor     = "255 255 255";
+    fontColorHL   = "255 255 255";
+    fontColorNA   = "255 255 255";
+    fontColorSEL  = "255 255 255";
+};
+
+singleton GuiControlProfile( VEditorTestProfile )
+{
+    opaque        = true;
+    fillColor     = "255 255 0";
+    fillColorHL   = "255 255 0";
+    fillColorNA   = "255 255 0";
+};
+
+singleton GuiControlProfile( VEditorNoFillProfile : VEditorDefaultProfile )
+{
+    opaque = false;
+};
+
+singleton GuiControlProfile( VEditorNoBorderProfile : VEditorDefaultProfile )
+{
+    border = false;
+};
+
+singleton GuiControlProfile( VEditorTransparentProfile : VEditorDefaultProfile )
+{
+    opaque = false;
+    border = false;
+};
+
+//-----------------------------------------------------------------------------
+
+singleton GuiControlProfile( VEditorTextProfile : VEditorDefaultProfile )
+{
+    border = false;
+    opaque = false;
+    
+    fontType = "Arial Bold";
+};
+
+singleton GuiControlProfile( VEditorTextEditProfile : VEditorDefaultProfile )
+{
+    fillColor      = "70 70 70";
+    fillColorHL    = "90 90 90";
+    fillColorSEL   = "0 0 0";
+    fillColorNA    = "70 70 70";
+    
+    fontColor      = "255 255 255";
+    fontColorHL    = "0 0 0";
+    fontColorSEL   = "128 128 128";
+    fontColorNA    = "128 128 128";
+    
+    textOffset     = "4 2";
+    autoSizeWidth  = false;
+    autoSizeHeight = false;
+    justify        = "left";
+    tab            = true;
+    canKeyFocus    = true;
+};
+
+singleton GuiControlProfile( VEditorPopupMenuProfile : GuiPopUpMenuProfile )
+{
+    FillColorHL    = "90 90 90";
+    FillColorSEL   = "0 0 0";
+    
+    FontColorHL    = "255 255 255";
+};
+
+singleton GuiControlProfile ( VEditorBitmapButtonProfile : VEditorDefaultProfile  )
+{
+    justify = "center";
+    
+    hasBitmapArray = true;
+    bitmap         = "./Images/Button";
+};
+
+//-----------------------------------------------------------------------------
+
+singleton GuiControlProfile( VEditorGroupHeaderProfile : VEditorDefaultProfile )
+{
+    CanKeyFocus = true;
+    TextOffset  = "23 0";
+    
+    fontColor   = "70 70 70";
+};
+
+singleton GuiControlProfile( VEditorGroupHeaderErrorProfile : VEditorGroupHeaderProfile )
+{
+    fontColor = "255 70 70";
+};
+
+singleton GuiControlProfile( VEditorGroupTrackProfile : VEditorTransparentProfile )
+{
+    CanKeyFocus = true;
+};
+
+singleton GuiControlProfile( VEditorTrackProfile : VEditorDefaultProfile )
+{
+    CanKeyFocus = true;
+    TextOffset  = "33 0";
+    
+    opaque      = true;
+    fillColor   = "255 255 255 15";
+    fillColorHL = "151 166 191 60";
+    
+    borderColor = "100 100 100";
+};
+
+singleton GuiControlProfile( VEditorTrackErrorProfile : VEditorTrackProfile )
+{
+    fontColor = "255 70 70";
+};
+
+singleton GuiControlProfile( VEditorEventProfile : VEditorDefaultProfile )
+{
+    CanKeyFocus   = true;
+    Justify       = "left";
+    TextOffset    = "6 1";
+    
+    fillColor     = "81 81 81";
+    fillColorHL   = "102 102 102";
+    
+    borderColor   = "255 255 255";
+    borderColorHL = "255 255 255";
+    borderColorNA = "100 100 100";
+};
+
+singleton GuiControlProfile( VEditorTimeLineProfile : VEditorDefaultProfile )
+{
+    CanKeyFocus = true;
+    
+    opaque      = false;
+    fillColorHL = "255 255 255 15";
+    
+    border      = false;
+    borderColor = "100 100 100";
+};
+
+singleton GuiControlProfile( VEditorPropertyProfile : VEditorDefaultProfile )
+{
+    fillColor = "102 102 102";
+};
+
+//-----------------------------------------------------------------------------
+
+singleton GuiControlProfile ( VEditorScrollProfile : VEditorDefaultProfile )
+{
+    opaque = false;
+    border = false;
+    
+    hasBitmapArray = true;
+    bitmap         = "./Images/ScrollBar";
+};
+
+singleton GuiControlProfile ( VEditorCheckBoxProfile : GuiCheckBoxProfile )
+{
+    // Void.
+};
+
+//-----------------------------------------------------------------------------
+
+singleton GuiControlProfile( VEditorPropertyRolloutProfile : GuiRolloutProfile )
+{
+    border = 0;
+    hasBitmapArray = true;
+    bitmap = "./Images/PropertyRollout";
+
+    fontType      = "Arial";
+    fontSize      = 12;
+    fontCharset   = ANSI;
+
+    fontColor     = "255 255 255";
+    fontColorHL   = "255 255 255";
+    fontColorNA   = "255 255 255";
+    fontColorSEL  = "255 255 255";
+};
+
+singleton GuiControlProfile( VEditorPropertyLabelProfile : VEditorTextProfile )
+{
+    border  = "1";
+    justify = "center";
+};
+
+//-----------------------------------------------------------------------------
+
+singleton GuiControlProfile( VEditorPreferenceLabelProfile : GuiTextProfile )
+{
+    opaque      = true;
+    fillColor   = "242 241 240";
+    fillColorHL = "242 241 240";
+    fillColorNA = "242 241 240";
+};

+ 103 - 0
Templates/BaseGame/game/tools/MainEditor/scripts/newEditorGui.cs

@@ -0,0 +1,103 @@
+function NewEditorGui::AddWindow(%this)
+{
+   %page = new GuiTabPageCtrl()
+   {
+      fitBook = "1";
+      text = "Object Viewer";
+      maxLength = "1024";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "0 0";
+      extent = "1024 768";
+      minExtent = "8 2";
+      horizSizing = "width";
+      vertSizing = "height";
+      profile = "GuiTabPageProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   
+   %page.add(ObjectViewer);
+   
+   MainEditorBasePanel.add(%page);
+   
+   //Ensure the sidebar is spaced sanely
+   %pos = MainEditorBasePanel.extent.x * 0.8;
+   ObjectViewer-->splitContainer.splitPoint.x = MainEditorBasePanel.extent.x * 0.8;
+   
+}
+
+function AssetBrowserWindow::onMouseDragged(%this)
+{
+   %payload = new GuiBitmapButtonCtrl();
+   %payload.assignFieldsFrom( %this );
+   %payload.className = "AssetPreviewControl";
+   %payload.position = "0 0";
+   %payload.dragSourceControl = %this;
+   %payload.bitmap = %this.icon;
+   %payload.extent.x /= 2;
+   %payload.extent.y /= 2;
+   
+   %xOffset = getWord( %payload.extent, 0 ) / 2;
+   %yOffset = getWord( %payload.extent, 1 ) / 2;
+   
+   // Compute the initial position of the GuiDragAndDrop control on the cavas based on the current
+   // mouse cursor position.
+   
+   %cursorpos = Canvas.getCursorPos();
+   %xPos = getWord( %cursorpos, 0 ) - %xOffset;
+   %yPos = getWord( %cursorpos, 1 ) - %yOffset;
+   
+   if(!isObject(EditorDragAndDropLayer))
+   {
+      new GuiControl(EditorDragAndDropLayer)
+      {
+         position = "0 0";
+         extent = Canvas.extent;
+      };
+   }
+   
+   // Create the drag control.
+   %ctrl = new GuiDragAndDropControl()
+   {
+      canSaveDynamicFields    = "0";
+      Profile                 = "GuiSolidDefaultProfile";
+      HorizSizing             = "right";
+      VertSizing              = "bottom";
+      Position                = %xPos SPC %yPos;
+      extent                  = %payload.extent;
+      MinExtent               = "4 4";
+      canSave                 = "1";
+      Visible                 = "1";
+      hovertime               = "1000";
+
+      // Let the GuiDragAndDropControl delete itself on mouse-up.  When the drag is aborted,
+      // this not only deletes the drag control but also our payload.
+      deleteOnMouseUp         = true;
+      
+      useWholeCanvas = true;
+
+      // To differentiate drags, use the namespace hierarchy to classify them.
+      // This will allow a color swatch drag to tell itself apart from a file drag, for example.
+      class                   = "AssetPreviewControlType_AssetDrop";
+   };
+   
+   // Add the temporary color swatch to the drag control as the payload.
+   %ctrl.add( %payload );
+   
+   // Start drag by adding the drag control to the canvas and then calling startDragging().
+   //Canvas.getContent().add( %ctrl );
+   EditorDragAndDropLayer.add(%ctrl);
+   Canvas.pushDialog(EditorDragAndDropLayer);
+   
+   %ctrl.startDragging( %xOffset, %yOffset );
+}

+ 26 - 0
Templates/BaseGame/game/tools/Tools.cs

@@ -0,0 +1,26 @@
+
+function ToolsModule::onCreate(%this)
+{
+   // ----------------------------------------------------------------------------
+   // Initialize core sub system functionality such as audio, the Canvas, PostFX,
+   // rendermanager, light managers, etc.
+   //
+   // Note that not all of these need to be initialized before the client, although
+   // the audio should and the canvas definitely needs to be.  I've put things here
+   // to distinguish between the purpose and functionality of the various client
+   // scripts.  Game specific script isn't needed until we reach the shell menus
+   // and start a game or connect to a server. We get the various subsystems ready
+   // to go, and then use initClient() to handle the rest of the startup sequence.
+   //
+   // If this is too convoluted we can reduce this complexity after futher testing
+   // to find exactly which subsystems should be readied before kicking things off. 
+   // ----------------------------------------------------------------------------
+   
+   ModuleDatabase.LoadExplicit( "MainEditor" );
+   ModuleDatabase.LoadExplicit( "Tools_ObjectViewer" );
+}
+
+function ToolsModule::onDestroy(%this)
+{
+
+}

+ 8 - 0
Templates/BaseGame/game/tools/Tools.module

@@ -0,0 +1,8 @@
+<ModuleDefinition
+	ModuleId="ToolsModule"
+	VersionId="1"
+	Description="Module that implements the tools and editor suite."
+	ScriptFile="Tools.cs"
+	CreateFunction="onCreate"
+	DestroyFunction="onDestroy"
+	Group="Tools"/>

+ 4 - 0
Templates/BaseGame/game/tools/gui/profiles.ed.cs

@@ -1077,6 +1077,10 @@ singleton GuiControlProfile( GuiMenuBarProfile )
    fillcolorHL = "42 42 42";
    borderColor = "30 30 30 255";
    borderColorHL = "30 30 30 255";
+   fontColor = "215 215 215";
+   fontColorSEL = "43 107 206";
+   fontColorHL = "244 244 244";
+   fontColorNA = "100 100 100";
    border = 0;
    borderThickness = 1;
    opaque = true;

+ 7 - 0
Templates/BaseGame/game/tools/main.cs

@@ -142,6 +142,13 @@ package Tools
       // resources can override, redefine, or add functionality.
       Tools::LoadResources( $Tools::resourcePath );
       
+      //Now, go through and load any tool-group modules
+      ModuleDatabase.setModuleExtension("module");
+      
+      //Any common tool modules
+      ModuleDatabase.scanModules( "tools", false );
+      ModuleDatabase.LoadGroup( "Tools" );
+      
       //Now that we're done loading, we can set the instant group back
       popInstantGroup();
       $instantGroup = MissionCleanup;

+ 24 - 3
Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui

@@ -4476,7 +4476,7 @@
             isContainer = "0";
             HorizSizing = "left";
             VertSizing = "bottom";
-            position = "86 1";
+            position = "66 1";
             Extent = "16 16";
             MinExtent = "8 2";
             canSave = "1";
@@ -4497,7 +4497,7 @@
             Profile = "ToolsGuiDefaultProfile";
             HorizSizing = "left";
             VertSizing = "bottom";
-            position = "106 1";
+            position = "86 1";
             Extent = "16 16";
             MinExtent = "8 2";
             canSave = "1";
@@ -4519,7 +4519,7 @@
             Profile = "ToolsGuiDefaultProfile";
             HorizSizing = "left";
             VertSizing = "bottom";
-            position = "123 1";
+            position = "106 1";
             Extent = "16 16";
             MinExtent = "8 2";
             canSave = "1";
@@ -4533,6 +4533,27 @@
             useMouseEvents = "0";
             bitmap = "tools/gui/images/save-icon";
          };
+         new GuiBitmapButtonCtrl() {
+            canSaveDynamicFields = "0";
+            Enabled = "1";
+            isContainer = "0";
+            Profile = "ToolsGuiDefaultProfile";
+            HorizSizing = "left";
+            VertSizing = "bottom";
+            position = "126 1";
+            Extent = "16 16";
+            MinExtent = "8 2";
+            canSave = "1";
+            Visible = "1";
+            Command = "MaterialEditorGui.lookupMaterialInstances();";
+            hovertime = "1000";
+            groupNum = "-1";
+            text ="";
+            tooltip = "Lookup Material Instances";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            bitmap = "tools/gui/images/visible";
+         };
          new GuiBitmapCtrl(){
             position = "147 1";
             Extent = "2 16";

+ 4 - 0
Templates/BaseGame/game/tools/materialEditor/main.cs

@@ -32,9 +32,13 @@ function initializeMaterialEditor()
    // Load Properties Window
    exec("~/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui");
    
+   //Material Instance viewer
+   exec("~/materialEditor/gui/materialInstancesView.ed.gui");
+   
    // Load Client Scripts.
    exec("./scripts/materialEditor.ed.cs");
    exec("./scripts/materialEditorUndo.ed.cs");
+   exec("./scripts/materialInstanceView.ed.cs");
    //exec("./gui/profiles.ed.cs");
    
    MaterialEditorPreviewWindow.setVisible( false );

+ 26 - 0
Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.cs

@@ -2278,6 +2278,32 @@ function MaterialEditorGui::refreshMaterial(%this)
    MaterialEditorGui.setMaterialNotDirty();
 }
 
+//==============================================================================
+// Looking up material instances/getting mat info 
+function MaterialEditorGui::lookupMaterialInstances( %this )
+{
+   if( MaterialEditorGui.currentMaterial.getName() $= "" )
+   {
+      MessageBoxOK("Cannot perform operation", "Unable to look up a material with a blank name" );
+      return;   
+   }
+   
+   MaterialInstanceViewTree.clear();
+   MaterialInstanceViewTree.setFilterChildren(false);
+   MaterialInstanceViewTree.setItemFilterException(1, true);
+   
+   MaterialEditorGui.currentMaterial.getMaterialInstances(MaterialInstanceViewTree);
+   
+   if(MaterialInstanceFilter.Text !$= "\c2Filter...")
+   {
+      MaterialInstanceViewTree.setFilterText(MaterialInstanceFilter.Text);
+   }
+   
+   MaterialInstanceViewTree.buildVisibleTree(true);
+   
+   Canvas.pushDialog(MaterialInstanceViewCtrl);
+}
+
 //==============================================================================
 // Switching and Changing Materials
 

+ 207 - 0
Templates/Full/game/tools/MainEditor/MainEditor.cs

@@ -0,0 +1,207 @@
+function MainEditor::onCreate( %this )
+{
+   echo("\n--------- Initializing MainEditor ---------");
+   
+   //exec("tools/gui/profiles.ed.cs");
+   //exec("./scripts/GuiProfiles.cs");
+
+   exec("./guis/MainEditorWindow.gui");
+   
+   //exec("./scripts/newEditorGui.cs");
+   
+   $UsePanelLayout = false;
+   $AssetBrowserPanelState = true;
+   $AssetBrowserPanelSplit = 0;
+   $InspectorPanelState = true;
+   $InspectorPanelSplit = 0;
+   $ToolsPanelState = true;
+   $ToolsPanelSplit = 0;
+}
+
+function MainEditor::onDestroy( %this )
+{
+}
+
+function NewEditorGui::addNewEditorTab(%this, %editorName)
+{
+   %editorTab = new GuiTabPageCtrl()
+   {
+      Profile = "ToolsGuiEditorTabPage";
+      position = "0 0";
+      extent = Editor_MainViewTabBook.extent;
+      AnchorTop = "1";
+      AnchorBottom = "0";
+      AnchorLeft = "1";
+      AnchorRight = "0";
+      horizSizing = "width";
+      vertSizing = "height";
+      text = %editorName;
+   };
+   
+   Editor_MainViewTabBook.add(%editorTab);
+   
+   return %editorTab;
+}
+
+function togglePanelLayout()
+{
+   $UsePanelLayout = !$UsePanelLayout;
+   
+   if($UsePanelLayout)
+   {
+      EditorGui.add(NewEditorGui);
+      
+      //Nudge us down so we show the toolbar
+      NewEditorGui.resize(0, EditorGuiToolbar.extent.y, EditorGui.extent.x, EditorGui.extent.y - EditorGuiToolbar.extent.y - EditorGuiStatusBar.extent.y);
+      
+      %mainEditViewTitle = "Level - " @ getScene(0).getName();
+      %mainEditViewCtrl = NewEditorGui.addNewEditorTab(%mainEditViewTitle);
+      
+      %mainEditViewCtrl.add(EWorldEditor);
+      EWorldEditor.position = "0 24";
+      EWorldEditor.extent = %mainEditViewCtrl.extent.x SPC %mainEditViewCtrl.extent.y - 24;
+      
+      Editor_AssetBrowserPanel.add(AssetBrowser);
+      AssetBrowser.resize(0,0, Editor_AssetBrowserPanel.extent.x, Editor_AssetBrowserPanel.extent.y);
+      AssetBrowser.horizSizing = "width";
+      AssetBrowser.vertSizing = "height";
+      AssetBrowserWindow.resize(0,0, AssetBrowser.extent.x, AssetBrowser.extent.y);
+      AssetBrowserWindow.horizSizing = "width";
+      AssetBrowserWindow.vertSizing = "height";
+      AssetBrowserWindow.canClose = false;
+      AssetBrowserWindow.canCollapse = false;
+      AssetBrowserWindow.canMaximize = false;
+      AssetBrowserWindow.canMinimize = false;
+      AssetBrowserWindow.canMove = false;
+      AssetBrowserWindow.resizeWidth = false;
+      AssetBrowserWindow.resizeHeight = false;
+      
+      //Prep it
+      AssetBrowser.loadFilters();
+     
+      Editor_SceneTreePanel.add(EWTreeWindow);
+      EWTreeWindow.resize(0,0, Editor_SceneTreePanel.extent.x, Editor_SceneTreePanel.extent.y);
+      EWTreeWindow.horizSizing = "width";
+      EWTreeWindow.vertSizing = "height";
+      EWTreeWindow.canClose = false;
+      EWTreeWindow.canCollapse = false;
+      EWTreeWindow.canMaximize = false;
+      EWTreeWindow.canMinimize = false;
+      EWTreeWindow.canMove = false;
+      EWTreeWindow.resizeWidth = false;
+      EWTreeWindow.resizeHeight = false;
+      
+      if(!isObject(Scenes))
+      {
+         $scenesRootGroup = new SimGroup(Scenes);
+      
+         $scenesRootGroup.add(getScene(0));
+      }
+      
+      EditorTree.open($scenesRootGroup,true);
+      
+      Editor_PropertiesPanel.add(EWInspectorWindow);
+      EWInspectorWindow.resize(0,0, Editor_PropertiesPanel.extent.x, Editor_PropertiesPanel.extent.y);
+      EWInspectorWindow.horizSizing = "width";
+      EWInspectorWindow.vertSizing = "height";
+      EWInspectorWindow.canClose = false;
+      EWInspectorWindow.canCollapse = false;
+      EWInspectorWindow.canMaximize = false;
+      EWInspectorWindow.canMinimize = false;
+      EWInspectorWindow.canMove = false;
+      EWInspectorWindow.resizeWidth = false;
+      EWInspectorWindow.resizeHeight = false;
+   }
+   else
+   {
+      EditorGui.remove(NewEditorGui);
+      
+      EditorGui.add(EWorldEditor);
+      
+      EditorGui.add(AssetBrowser);
+      AssetBrowserWindow.canClose = false;
+      AssetBrowserWindow.canCollapse = false;
+      AssetBrowserWindow.canMaximize = false;
+      AssetBrowserWindow.canMinimize = false;
+      AssetBrowserWindow.canMove = false;
+      
+      EditorGui.add(EWTreeWindow);
+      
+      EditorGui.add(EWInspectorWindow);
+   }
+}
+
+function Editor_AssetBrowserButton::onClick(%this)
+{
+   $AssetBrowserPanelState = !$AssetBrowserPanelState;
+   
+   //If we're collapsing
+   if(!$AssetBrowserPanelState)
+   {
+      //Store the original
+      $AssetBrowserPanelSplit = Editor_MainViewSplit.splitPoint.y;
+      
+      //collapse it
+      Editor_MainViewSplit.setSplitPoint(Editor_MainViewSplit.splitPoint.x SPC  Editor_MainViewSplit.extent.y - Editor_MainViewSplit.splitterSize);
+   }
+   else
+   {
+      //restore the original
+      Editor_MainViewSplit.setSplitPoint(Editor_MainViewSplit.splitPoint.x SPC $AssetBrowserPanelSplit);
+   }
+}
+
+function Editor_InspectorSidebarButton::onClick(%this)
+{
+   $InspectorPanelState = !$InspectorPanelState;
+   
+   //If we're collapsing
+   if(!$InspectorPanelState)
+   {
+      //Store the original
+      $InspectorPanelSplit = NewEditorGuiLayout.splitPoint.x;
+      
+      //collapse it
+      NewEditorGuiLayout.setSplitPoint(NewEditorGui.extent.x - NewEditorGuiLayout.splitterSize SPC NewEditorGuiLayout.splitPoint.y);
+   }
+   else
+   {
+      //restore the original
+      NewEditorGuiLayout.setSplitPoint($InspectorPanelSplit SPC NewEditorGuiLayout.splitPoint.y);
+   }
+}
+
+function Editor_ToolsSidebarButton::onClick(%this)
+{
+   $ToolsPanelState = !$ToolsPanelState;
+   
+   //If we're collapsing
+   if(!$ToolsPanelState)
+   {
+      //Store the original
+      $ToolsPanelSplit = Editor_ToolsMainSplit.splitPoint.x;
+      
+      //collapse it
+      Editor_ToolsMainSplit.setSplitPoint(Editor_ToolsMainSplit.splitterSize SPC Editor_ToolsMainSplit.splitPoint.y);
+   }
+   else
+   {
+      //restore the original
+      Editor_ToolsMainSplit.setSplitPoint($ToolsPanelSplit SPC Editor_ToolsMainSplit.splitPoint.y);
+   }
+}
+
+function Editor_VisibilityOptionsButton::onClick(%this)
+{
+   if ( EVisibility.visible  )
+   {
+      EVisibility.setVisible(false);
+      //visibilityToggleBtn.setStateOn(0);
+   }
+   else
+   {
+      EVisibility.setVisible(true);
+      //visibilityToggleBtn.setStateOn(1);
+      EVisibility.setExtent("200 540");
+   }  
+}

+ 9 - 0
Templates/Full/game/tools/MainEditor/MainEditor.module

@@ -0,0 +1,9 @@
+<ModuleDefinition
+	ModuleId="MainEditor"
+	VersionId="1"
+	Description="Tool that can be used to view/edit an object."
+	ScriptFile="MainEditor.cs"
+	CreateFunction="onCreate"
+	DestroyFunction="onDestroy"
+	Group="Tools">
+</ModuleDefinition>

二进制
Templates/Full/game/tools/MainEditor/art/Button.png


二进制
Templates/Full/game/tools/MainEditor/art/GroupBackground.png


二进制
Templates/Full/game/tools/MainEditor/art/GroupBackground_h.png


二进制
Templates/Full/game/tools/MainEditor/art/GroupBackground_i.png


二进制
Templates/Full/game/tools/MainEditor/art/PropertyRollout.png


二进制
Templates/Full/game/tools/MainEditor/art/ScrollBar.png


二进制
Templates/Full/game/tools/MainEditor/art/ScrollBar_.png


二进制
Templates/Full/game/tools/MainEditor/art/Spacer.png


二进制
Templates/Full/game/tools/MainEditor/art/btn_AddEvent.png


二进制
Templates/Full/game/tools/MainEditor/art/btn_AddEvent_d.png


二进制
Templates/Full/game/tools/MainEditor/art/btn_AddEvent_h.png


部分文件因为文件数量过多而无法显示