Explorar o código

Merge branch 'PreviewAssets_UseAsset' into SoundAsset_Refactor

marauder2k7 hai 2 meses
pai
achega
c6ec2fd6a1
Modificáronse 24 ficheiros con 391 adicións e 125 borrados
  1. 54 40
      Engine/source/T3D/assets/ImageAsset.cpp
  2. 32 12
      Engine/source/T3D/assets/ImageAsset.h
  3. 4 26
      Engine/source/T3D/assets/assetImporter.cpp
  4. 64 2
      Engine/source/T3D/fps/guiCrossHairHud.cpp
  5. 19 3
      Engine/source/assets/assetBase.cpp
  6. 17 0
      Engine/source/console/console.cpp
  7. 9 0
      Engine/source/gui/core/guiCanvas.cpp
  8. 3 1
      Engine/source/gui/core/guiOffscreenCanvas.cpp
  9. 5 0
      Engine/source/gui/core/guiOffscreenCanvas.h
  10. 4 0
      Engine/source/gui/core/guiTypes.cpp
  11. 15 0
      Templates/BaseGame/game/data/Prototyping/Prototyping.tscript
  12. 11 0
      Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/ScreenTarget.asset.taml
  13. 14 0
      Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_base_mat.asset.taml
  14. 16 0
      Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_screen_mat.asset.taml
  15. 6 0
      Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.asset.taml
  16. BIN=BIN
      Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.fbx
  17. 20 0
      Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.tscript
  18. 2 2
      Templates/BaseGame/game/data/UI/scripts/cursors.tscript
  19. 2 2
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript
  20. 28 4
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript
  21. 28 7
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript
  22. 24 12
      Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript
  23. 6 6
      Templates/BaseGame/game/tools/gui/cursors.ed.tscript
  24. 8 8
      Templates/BaseGame/game/tools/worldEditor/scripts/cursors.ed.tscript

+ 54 - 40
Engine/source/T3D/assets/ImageAsset.cpp

@@ -213,6 +213,8 @@ bool ImageAsset::onAdd()
 
 void ImageAsset::onRemove()
 {
+   Torque::FS::RemoveChangeNotification(mImageFile, this, &ImageAsset::_onResourceChanged);
+
    // Call Parent.
    Parent::onRemove();
 }
@@ -345,6 +347,11 @@ void ImageAsset::initializeAsset(void)
       return;
 
    mImageFile = expandAssetFilePath(mImageFile);
+
+   if (getOwned())
+      Torque::FS::AddChangeNotification(mImageFile, this, &ImageAsset::_onResourceChanged);
+
+   populateImage();
 }
 
 void ImageAsset::onAssetRefresh(void)
@@ -356,6 +363,8 @@ void ImageAsset::onAssetRefresh(void)
    // Call parent.
    Parent::onAssetRefresh();
 
+   populateImage();
+
 }
 
 //------------------------------------------------------------------------------
@@ -385,6 +394,8 @@ void ImageAsset::setImageFile(StringTableEntry pImageFile)
    if (pImageFile == mImageFile)
       return;
 
+   Torque::FS::RemoveChangeNotification(mImageFile, this, &ImageAsset::_onResourceChanged);
+
    if (String(pImageFile).startsWith("#") || String(pImageFile).startsWith("$"))
    {
       mImageFile = StringTable->insert(pImageFile);
@@ -395,46 +406,6 @@ void ImageAsset::setImageFile(StringTableEntry pImageFile)
 
    mImageFile = getOwned() ? expandAssetFilePath(pImageFile) : StringTable->insert(pImageFile);
 
-   if (Torque::FS::IsFile(mImageFile))
-   {
-      if (dStrEndsWith(mImageFile, ".dds"))
-      {
-         DDSFile* tempFile = new DDSFile();
-         FileStream* ddsFs;
-         if ((ddsFs = FileStream::createAndOpen(mImageFile, Torque::FS::File::Read)) == NULL)
-         {
-            Con::errorf("ImageAsset::setImageFile Failed to open ddsfile: %s", mImageFile);
-         }
-
-         if (!tempFile->readHeader(*ddsFs))
-         {
-            Con::errorf("ImageAsset::setImageFile Failed to read header of ddsfile: %s", mImageFile);
-         }
-         else
-         {
-            mImageWidth = tempFile->mWidth;
-            mImageHeight = tempFile->mHeight;
-         }
-
-         ddsFs->close();
-         delete tempFile;
-      }
-      else
-      {
-         if (!stbi_info(mImageFile, &mImageWidth, &mImageHeight, &mImageChannels))
-         {
-            StringTableEntry stbErr = stbi_failure_reason();
-            if (stbErr == StringTable->EmptyString())
-               stbErr = "ImageAsset::Unkown Error!";
-
-            Con::errorf("ImageAsset::setImageFile STB Get file info failed: %s", stbErr);
-         }
-      }
-
-      // we only support 2d textures..... for no ;)
-      mImageDepth = 1;
-   }
-
    refreshAsset();
 }
 
@@ -675,6 +646,49 @@ void ImageAsset::onTamlCustomRead(const TamlCustomNodes& customNodes)
    }
 }
 
+void ImageAsset::populateImage(void)
+{
+   if (Torque::FS::IsFile(mImageFile))
+   {
+      if (dStrEndsWith(mImageFile, ".dds"))
+      {
+         DDSFile* tempFile = new DDSFile();
+         FileStream* ddsFs;
+         if ((ddsFs = FileStream::createAndOpen(mImageFile, Torque::FS::File::Read)) == NULL)
+         {
+            Con::errorf("ImageAsset::setImageFile Failed to open ddsfile: %s", mImageFile);
+         }
+
+         if (!tempFile->readHeader(*ddsFs))
+         {
+            Con::errorf("ImageAsset::setImageFile Failed to read header of ddsfile: %s", mImageFile);
+         }
+         else
+         {
+            mImageWidth = tempFile->mWidth;
+            mImageHeight = tempFile->mHeight;
+         }
+
+         ddsFs->close();
+         delete tempFile;
+      }
+      else
+      {
+         if (!stbi_info(mImageFile, &mImageWidth, &mImageHeight, &mImageChannels))
+         {
+            StringTableEntry stbErr = stbi_failure_reason();
+            if (stbErr == StringTable->EmptyString())
+               stbErr = "ImageAsset::Unkown Error!";
+
+            Con::errorf("ImageAsset::setImageFile STB Get file info failed: %s", stbErr);
+         }
+      }
+
+      // we only support 2d textures..... for now ;)
+      mImageDepth = 1; 
+   }
+}
+
 const char* ImageAsset::getImageInfo()
 {
    if (isAssetValid())

+ 32 - 12
Engine/source/T3D/assets/ImageAsset.h

@@ -123,7 +123,7 @@ public:
    };
 
    static const String mErrCodeStrings[U32(ImageAssetErrCode::Extended) - U32(Parent::Extended) + 1];
-   static U32 getAssetErrCode(ConcreteAssetPtr checkAsset) { if (checkAsset) return checkAsset->mLoadedState; else return 0; }
+   static U32 getAssetErrCode(ConcreteAssetPtr checkAsset) { if (checkAsset.notNull()) return checkAsset->mLoadedState; else return 0; }
 
    static String getAssetErrstrn(U32 errCode)
    {
@@ -196,7 +196,7 @@ public:
    static U32 getAssetById(StringTableEntry assetId, AssetPtr<ImageAsset>* imageAsset);
    static U32 getAssetById(String assetId, AssetPtr<ImageAsset>* imageAsset) { return getAssetById(assetId.c_str(), imageAsset); };
 
-
+   void populateImage(void);
    const char* getImageInfo();
 
 protected:
@@ -233,17 +233,20 @@ DefineEnumType(ImageAssetType);
 
 #pragma region Refactor Asset Macros
 
-#define DECLARE_IMAGEASSET(className, name, profile)                                                                                                                 \
+#define DECLARE_IMAGEASSET(className, name, profile)                                                                                                                          \
 private:                                                                                                                                                                      \
-   AssetPtr<ImageAsset> m##name##Asset;\
-   String               m##name##File;\
+   AssetPtr<ImageAsset> m##name##Asset;                                                                                                                                       \
+   StringTableEntry     m##name##File  = StringTable->EmptyString();                                                                                                          \
 public:                                                                                                                                                                       \
    void _set##name(StringTableEntry _in){                                                                                                                                     \
       if(m##name##Asset.getAssetId() == _in)                                                                                                                                  \
          return;                                                                                                                                                              \
+      if(get##name##File() == _in)                                                                                                                                            \
+         return;                                                                                                                                                              \
       if(_in == NULL || _in == StringTable->EmptyString())                                                                                                                    \
       {                                                                                                                                                                       \
          m##name##Asset = NULL;                                                                                                                                               \
+         m##name##File = "";                                                                                                                                                  \
          return;                                                                                                                                                              \
       }                                                                                                                                                                       \
       if(!AssetDatabase.isDeclaredAsset(_in))                                                                                                                                 \
@@ -271,10 +274,12 @@ public:
             imageAssetId = ImageAsset::smNoImageAssetFallback;                                                                                                                \
          }                                                                                                                                                                    \
          m##name##Asset = imageAssetId;                                                                                                                                       \
+         m##name##File = _in;                                                                                                                                                 \
       }                                                                                                                                                                       \
       else                                                                                                                                                                    \
       {                                                                                                                                                                       \
          m##name##Asset = _in;                                                                                                                                                \
+         m##name##File = get##name##File();                                                                                                                                   \
       }                                                                                                                                                                       \
    };                                                                                                                                                                         \
                                                                                                                                                                               \
@@ -285,17 +290,20 @@ public:
    StringTableEntry get##name##File(){ return m##name##Asset.notNull() ? m##name##Asset->getImageFile() : ""; }
 
 
-#define DECLARE_IMAGEASSET_NET(className, name, profile, mask)                                                                                                       \
+#define DECLARE_IMAGEASSET_NET(className, name, profile, mask)                                                                                                                \
 private:                                                                                                                                                                      \
    AssetPtr<ImageAsset> m##name##Asset;                                                                                                                                       \
-   String               m##name##File;\
+   StringTableEntry     m##name##File  = StringTable->EmptyString();                                                                                                          \
 public:                                                                                                                                                                       \
    void _set##name(StringTableEntry _in){                                                                                                                                     \
       if(m##name##Asset.getAssetId() == _in)                                                                                                                                  \
          return;                                                                                                                                                              \
+      if(get##name##File() == _in)                                                                                                                                            \
+         return;                                                                                                                                                              \
       if(_in == NULL || _in == StringTable->EmptyString())                                                                                                                    \
       {                                                                                                                                                                       \
          m##name##Asset = NULL;                                                                                                                                               \
+         m##name##File = "";                                                                                                                                                  \
          setMaskBits(mask);                                                                                                                                                   \
          return;                                                                                                                                                              \
       }                                                                                                                                                                       \
@@ -324,10 +332,12 @@ public:
             imageAssetId = ImageAsset::smNoImageAssetFallback;                                                                                                                \
          }                                                                                                                                                                    \
          m##name##Asset = imageAssetId;                                                                                                                                       \
+         m##name##File = _in;                                                                                                                                                 \
       }                                                                                                                                                                       \
       else                                                                                                                                                                    \
       {                                                                                                                                                                       \
          m##name##Asset = _in;                                                                                                                                                \
+         m##name##File = get##name##File();                                                                                                                                   \
       }                                                                                                                                                                       \
       setMaskBits(mask);                                                                                                                                                      \
    };                                                                                                                                                                         \
@@ -339,22 +349,25 @@ public:
    StringTableEntry get##name##File(){ return m##name##Asset.notNull() ? m##name##Asset->getImageFile() : ""; }
 
 
-#define INITPERSISTFIELD_IMAGEASSET(name, consoleClass, docs)                                                                                                        \
+#define INITPERSISTFIELD_IMAGEASSET(name, consoleClass, docs)                                                                                                                 \
    addProtectedField(assetText(name, Asset), TypeImageAssetPtr, Offset(m##name##Asset, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.)); \
    addProtectedField(assetText(name, File), TypeFilename, Offset(m##name##File, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, file docs.));
 
 
-#define DECLARE_IMAGEASSET_ARRAY(className, name, profile, max)                                                                                                      \
+#define DECLARE_IMAGEASSET_ARRAY(className, name, profile, max)                                                                                                               \
 private:                                                                                                                                                                      \
    AssetPtr<ImageAsset> m##name##Asset[max];                                                                                                                                  \
-   String               m##name##File[max];\
+   StringTableEntry     m##name##File[max] = {StringTable->EmptyString() };                                                                                                   \
 public:                                                                                                                                                                       \
    void _set##name(StringTableEntry _in, const U32& index){                                                                                                                   \
       if(m##name##Asset[index].getAssetId() == _in)                                                                                                                           \
          return;                                                                                                                                                              \
+      if(get##name##File(index) == _in)                                                                                                                                       \
+         return;                                                                                                                                                              \
       if(_in == NULL || _in == StringTable->EmptyString())                                                                                                                    \
       {                                                                                                                                                                       \
          m##name##Asset[index] = NULL;                                                                                                                                        \
+         m##name##File[index] = "";                                                                                                                                           \
          return;                                                                                                                                                              \
       }                                                                                                                                                                       \
       if(!AssetDatabase.isDeclaredAsset(_in))                                                                                                                                 \
@@ -382,10 +395,12 @@ public:
             imageAssetId = ImageAsset::smNoImageAssetFallback;                                                                                                                \
          }                                                                                                                                                                    \
          m##name##Asset[index] = imageAssetId;                                                                                                                                \
+         m##name##File[index] = _in;                                                                                                                                          \
       }                                                                                                                                                                       \
       else                                                                                                                                                                    \
       {                                                                                                                                                                       \
          m##name##Asset[index] = _in;                                                                                                                                         \
+         m##name##File[index] = get##name##File(index);                                                                                                                       \
       }                                                                                                                                                                       \
    };                                                                                                                                                                         \
                                                                                                                                                                               \
@@ -397,17 +412,20 @@ public:
    StringTableEntry get##name##File(const U32& idx){ return m##name##Asset[idx].notNull() ? m##name##Asset[idx]->getImageFile() : ""; }
 
 
-#define DECLARE_IMAGEASSET_ARRAY_NET(className, name, profile, max, mask)                                                                                            \
+#define DECLARE_IMAGEASSET_ARRAY_NET(className, name, profile, max, mask)                                                                                                     \
 private:                                                                                                                                                                      \
    AssetPtr<ImageAsset> m##name##Asset[max];                                                                                                                                  \
-   String               m##name##File[max];\
+   StringTableEntry     m##name##File[max] = {StringTable->EmptyString() };                                                                                                   \
 public:                                                                                                                                                                       \
    void _set##name(StringTableEntry _in, const U32& index){                                                                                                                   \
       if(m##name##Asset[index].getAssetId() == _in)                                                                                                                           \
          return;                                                                                                                                                              \
+      if(get##name##File(index) == _in)                                                                                                                                       \
+         return;                                                                                                                                                              \
       if(_in == NULL || _in == StringTable->EmptyString())                                                                                                                    \
       {                                                                                                                                                                       \
          m##name##Asset[index] = NULL;                                                                                                                                        \
+         m##name##File[index] = "";                                                                                                                                           \
          setMaskBits(mask);                                                                                                                                                   \
          return;                                                                                                                                                              \
       }                                                                                                                                                                       \
@@ -436,10 +454,12 @@ public:
             imageAssetId = ImageAsset::smNoImageAssetFallback;                                                                                                                \
          }                                                                                                                                                                    \
          m##name##Asset[index] = imageAssetId;                                                                                                                                \
+         m##name##File[index] = _in;                                                                                                                                          \
       }                                                                                                                                                                       \
       else                                                                                                                                                                    \
       {                                                                                                                                                                       \
          m##name##Asset[index] = _in;                                                                                                                                         \
+         m##name##File[index] = get##name##File(index);                                                                                                                       \
       }                                                                                                                                                                       \
       setMaskBits(mask);                                                                                                                                                      \
    };                                                                                                                                                                         \

+ 4 - 26
Engine/source/T3D/assets/assetImporter.cpp

@@ -2805,6 +2805,7 @@ void AssetImporter::acquireAssets(AssetImportObject* assetItem)
       if (AssetDatabase.isDeclaredAsset(assetId))
       {
          AssetDatabase.acquireAsset<AssetBase>(assetId);
+         AssetDatabase.refreshAsset(assetId);
          AssetDatabase.releaseAsset(assetId);
       }
    }
@@ -2825,29 +2826,18 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem)
    StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str());
 
    String imageFileName = assetItem->filePath.getFullFileName();
-   String assetPath = targetPath + "/" + imageFileName;
+   String assetPath = "@" + imageFileName;
    String tamlPath = targetPath + "/" + assetName + ".asset.taml";
    String originalPath = assetItem->filePath.getFullPath().c_str();
 
-   char qualifiedFromFile[2048];
-   char qualifiedToFile[2048];
-
-#ifndef TORQUE_SECURE_VFS
-   Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
-   Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
-#else
-   dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile));
-   dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile));
-#endif
-   
    newAsset->setAssetName(assetName);
    newAsset->setImageFile(assetPath.c_str());
 
    //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
    //file path for reimporting support later
-   if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile))
+   if (!isReimport)
    {
-      newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
+      newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, originalPath.c_str());
    }
 
    if (assetItem->typeHint != String::EmptyString)
@@ -2870,18 +2860,6 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem)
       return "";
    }
 
-   if (!isReimport)
-   {
-      bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile);
-
-      if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport))
-      {
-         dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str());
-         activityLog.push_back(importLogBuffer);
-         return "";
-      }
-   }
-
    return tamlPath;
 }
 

+ 64 - 2
Engine/source/T3D/fps/guiCrossHairHud.cpp

@@ -30,7 +30,11 @@
 #include "T3D/shapeBase.h"
 #include "gfx/gfxDrawUtil.h"
 #include "console/engineAPI.h"
-
+#include "gui/core/guiOffscreenCanvas.h"
+#include "T3D/tsStatic.h"
+#include "materials/baseMatInstance.h"
+#include "materials/matInstance.h"
+#include "materials/materialDefinition.h"
 
 //-----------------------------------------------------------------------------
 /// Vary basic cross hair hud.
@@ -46,12 +50,14 @@ class GuiCrossHairHud : public GuiBitmapCtrl
    LinearColorF   mDamageFrameColor;
    Point2I  mDamageRectSize;
    Point2I  mDamageOffset;
+   PlatformTimer* mFrameTime;
 
 protected:
    void drawDamage(Point2I offset, F32 damage, F32 opacity);
 
 public:
    GuiCrossHairHud();
+   ~GuiCrossHairHud();
 
    void onRender( Point2I, const RectI &) override;
    static void initPersistFields();
@@ -95,6 +101,12 @@ GuiCrossHairHud::GuiCrossHairHud()
    mDamageFrameColor.set( 1.0f, 0.6f, 0.0f, 1.0f );
    mDamageRectSize.set(50, 4);
    mDamageOffset.set(0,32);
+   mFrameTime = PlatformTimer::create();
+}
+
+GuiCrossHairHud::~GuiCrossHairHud()
+{
+   SAFE_DELETE(mFrameTime);
 }
 
 void GuiCrossHairHud::initPersistFields()
@@ -139,11 +151,61 @@ void GuiCrossHairHud::onRender(Point2I offset, const RectI &updateRect)
 
    // Collision info. We're going to be running LOS tests and we
    // don't want to collide with the control object.
-   static U32 losMask = TerrainObjectType | ShapeBaseObjectType;
+   static U32 losMask = TerrainObjectType | ShapeBaseObjectType | StaticShapeObjectType;
    control->disableCollision();
 
    RayInfo info;
    if (gClientContainer.castRay(camPos, endPos, losMask, &info)) {
+      // is this a tsstatic? then it could be a offscreen canvas, check the list.
+      if (TSStatic* ts = dynamic_cast<TSStatic*>(info.object))
+      {
+         if (mFrameTime->getElapsedMs() > 32)
+         {
+            GuiOffscreenCanvas::sActiveOffscreenCanvas = NULL;
+            mFrameTime->reset();
+
+            Point3F newStart, newEnd;
+            ts->getWorldTransform().mulP(camPos, &newStart);
+            ts->getWorldTransform().mulP(endPos, &newEnd);
+
+            newStart.convolveInverse(ts->getScale());
+            newEnd.convolveInverse(ts->getScale());
+
+            info.generateTexCoord = true;
+            if (ts->getShapeInstance()->castRayOpcode(0, newStart, newEnd, &info))
+            {
+               MatInstance* matInst = dynamic_cast<MatInstance*>(info.material);
+               if (matInst)
+               {
+                  Material* mat = matInst->getMaterial();
+                  if (mat && mat->getDiffuseMapAsset(0).notNull() && mat->getDiffuseMapAsset(0)->isNamedTarget())
+                  {
+                     String canvasName = String(mat->getDiffuseMapAsset(0)->getImageFile()).substr(1, (U32)strlen(mat->getDiffuseMapAsset(0)->getImageFile()) - 1);
+                     for (GuiOffscreenCanvas* canvas : GuiOffscreenCanvas::sList)
+                     {
+                        if (canvas->getTarget()->getName() == canvasName)
+                        {
+                           if (!canvas->canInteract() || canvas->getMaxInteractDistance() < info.distance)
+                           {
+                              break;
+                           }
+
+                           Point2I canvasSize = canvas->getWindowSize();
+                           Point2I newCursorPos(mRound(mClampF((info.texCoord.x * canvasSize.x), 0.0f, (F32)canvasSize.x)),
+                              mRound(mClampF((info.texCoord.y * canvasSize.y), 0.0f, (F32)canvasSize.y)));
+
+                           canvas->setCursorPos(newCursorPos);
+                           canvas->markDirty();
+                           GuiOffscreenCanvas::sActiveOffscreenCanvas = canvas;
+                           break;
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+
       // Hit something... but we'll only display health for named
       // ShapeBase objects.  Could mask against the object type here
       // and do a static cast if it's a ShapeBaseObjectType, but this

+ 19 - 3
Engine/source/assets/assetBase.cpp

@@ -226,9 +226,20 @@ StringTableEntry AssetBase::expandAssetFilePath(const char* pAssetFilePath) cons
       assetBasePathHint = NULL;
    }
 
-   // Expand the path with the asset base-path hint.
    char assetFilePathBuffer[1024];
-   Con::expandPath(assetFilePathBuffer, sizeof(assetFilePathBuffer), pAssetFilePath, assetBasePathHint);
+
+   if (*pAssetFilePath != '@')
+   {
+      // Expand the path with the asset base-path hint.
+      Con::expandPath(assetFilePathBuffer, sizeof(assetFilePathBuffer), pAssetFilePath, assetBasePathHint);
+      return StringTable->insert(assetFilePathBuffer);
+   }
+
+   if(!getOwned())
+      return StringTable->insert(pAssetFilePath);
+
+   // Format expanded path taking into account any missing slash.
+   dSprintf(assetFilePathBuffer, sizeof(assetFilePathBuffer), "%s/%s", mpOwningAssetManager->getAssetPath(getAssetId()), pAssetFilePath + (pAssetFilePath[1] == '/' ? 2 : 1));
    return StringTable->insert(assetFilePathBuffer);
 }
 
@@ -254,6 +265,11 @@ StringTableEntry AssetBase::collapseAssetFilePath(const char* pAssetFilePath) co
 
    char assetFilePathBuffer[1024];
 
+   if (*pAssetFilePath == '@')
+   {
+      return StringTable->insert(pAssetFilePath);
+   }
+
    // Is the asset not owned or private?
    if (!getOwned() || getAssetPrivate())
    {
@@ -272,7 +288,7 @@ StringTableEntry AssetBase::collapseAssetFilePath(const char* pAssetFilePath) co
       StringTableEntry relativePath = Platform::makeRelativePathName(pAssetFilePath, assetBasePath);
 
       // Format the collapsed path.
-      dSprintf(assetFilePathBuffer, sizeof(assetFilePathBuffer), "%s", relativePath);
+      dSprintf(assetFilePathBuffer, sizeof(assetFilePathBuffer), "@%s", relativePath);
    }
    else
    {

+ 17 - 0
Engine/source/console/console.cpp

@@ -2226,6 +2226,23 @@ bool stripRepeatSlashes(char* pDstPath, const char* pSrcPath, S32 dstSize)
 
 //-----------------------------------------------------------------------------
 
+DefineEngineFunction(expandPath, const char*, (const char* path),, "(string path) - Expands an expando or relative path into a full path.")
+{
+   char* ret = Con::getReturnBuffer(1024);
+   Con::expandPath(ret, 1024, path);
+   return ret;
+}
+
+//-----------------------------------------------------------------------------
+
+DefineEngineFunction(collapsePath, const char*, (const char* path), , "(string path) - Collapses a path into either an expando path or a relative path.")
+{
+   char* ret = Con::getReturnBuffer(1024);
+   Con::collapsePath(ret, 1024, path);
+   return ret;
+}
+
+
 DefineEngineFunction( log, void, ( const char* message ),,
    "@brief Logs a message to the console.\n\n"
    "@param message The message text.\n"

+ 9 - 0
Engine/source/gui/core/guiCanvas.cpp

@@ -690,6 +690,15 @@ bool GuiCanvas::processInputEvent(InputEventInfo &inputEvent)
    mConsumeLastInputEvent = true;
    mLastInputDeviceType = inputEvent.deviceType;
 
+   // If we have an active offscreen canvas, give it the input
+   if (GuiOffscreenCanvas::sActiveOffscreenCanvas &&
+      (GuiOffscreenCanvas::sActiveOffscreenCanvas != this) &&
+      GuiOffscreenCanvas::sActiveOffscreenCanvas->processInputEvent(inputEvent))
+   {
+      GuiOffscreenCanvas::sActiveOffscreenCanvas = NULL;
+      return mConsumeLastInputEvent;
+   }
+
    // First call the general input handler (on the extremely off-chance that it will be handled):
    if (mFirstResponder &&  mFirstResponder->onInputEvent(inputEvent))
    {

+ 3 - 1
Engine/source/gui/core/guiOffscreenCanvas.cpp

@@ -9,6 +9,7 @@
 
 IMPLEMENT_CONOBJECT(GuiOffscreenCanvas);
 
+GuiOffscreenCanvas* GuiOffscreenCanvas::sActiveOffscreenCanvas = NULL;
 Vector<GuiOffscreenCanvas*> GuiOffscreenCanvas::sList;
 
 GuiOffscreenCanvas::GuiOffscreenCanvas()
@@ -33,7 +34,8 @@ void GuiOffscreenCanvas::initPersistFields()
    addField( "targetName", TypeRealString, Offset( mTargetName, GuiOffscreenCanvas ), "");
    addField( "dynamicTarget", TypeBool, Offset( mDynamicTarget, GuiOffscreenCanvas ), "");
    addField( "useDepth", TypeBool, Offset( mUseDepth, GuiOffscreenCanvas ), "");
-
+   addField("canInteract", TypeBool, Offset(mCanInteract, GuiOffscreenCanvas), "");
+   addField("maxInteractDistance", TypeF32, Offset(mMaxInteractDistance, GuiOffscreenCanvas), "");
    Parent::initPersistFields();
 }
 

+ 5 - 0
Engine/source/gui/core/guiOffscreenCanvas.h

@@ -38,6 +38,8 @@ public:
    void _teardownTargets();
 
    NamedTexTargetRef getTarget() { return &mNamedTarget; }
+   bool canInteract() { return mCanInteract; }
+   F32 getMaxInteractDistance() { return mMaxInteractDistance; }
 
    void markDirty() { mTargetDirty = true; }
 
@@ -59,9 +61,12 @@ protected:
    
    bool mUseDepth;
    GFXTexHandle mTargetDepth;
+   bool mCanInteract;
+   F32 mMaxInteractDistance;
 
 public:
    static Vector<GuiOffscreenCanvas*> sList;
+   static GuiOffscreenCanvas* sActiveOffscreenCanvas;
 };
 
 #endif

+ 4 - 0
Engine/source/gui/core/guiTypes.cpp

@@ -116,6 +116,10 @@ void GuiCursor::render(const Point2I &pos)
    {
       mExtent.set(getBitmap()->getWidth(), getBitmap()->getHeight());
    }
+   else
+   {
+      return;
+   }
 
    // Render the cursor centered according to dimensions of texture
    S32 texWidth = getBitmap()->getWidth();

+ 15 - 0
Templates/BaseGame/game/data/Prototyping/Prototyping.tscript

@@ -42,6 +42,21 @@ function Prototyping::initClient(%this)
 //This is called when a client connects to a server
 function Prototyping::onCreateClientConnection(%this)
 {
+   if (!isObject(screen_Canvas))
+   {
+      new GuiOffscreenCanvas(screen_Canvas) {
+         targetName = "screen_Canvas";
+         targetSize = "1280 720";
+         dynamicTarget = false;
+         canInteract = true;
+         maxInteractDistance = "3";
+      };
+   }
+
+   if(isObject(OptionsMenu))
+   {
+      screen_Canvas.setContent(OptionsMenu);
+   }
 }
 
 //This is called when a client disconnects from a server

+ 11 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/ScreenTarget.asset.taml

@@ -0,0 +1,11 @@
+<ImageAsset
+    AssetName="ScreenTarget"
+    imageFile="@assetFile=#screen_Canvas"
+    VersionId="1">
+    <ImageAsset.ImageMetadata>
+        <ImageInfo
+            ImageWidth="-1"
+            ImageHeight="-1"
+            ImageDepth="-1"/>
+    </ImageAsset.ImageMetadata>
+</ImageAsset>

+ 14 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_base_mat.asset.taml

@@ -0,0 +1,14 @@
+<MaterialAsset
+    AssetName="monitor_base_mat"
+    materialDefinitionName="monitor_base_mat">
+    <Material
+        Name="monitor_base_mat"
+        mapTo="monitor_base_mat"
+        doubleSided="true"
+        originalAssetName="monitor_base_mat">
+        <Material.Stages>
+            <Stages_beginarray
+                DiffuseColor="0 0 0 1"/>
+        </Material.Stages>
+    </Material>
+</MaterialAsset>

+ 16 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_screen_mat.asset.taml

@@ -0,0 +1,16 @@
+<MaterialAsset
+    AssetName="monitor_screen_mat"
+    materialDefinitionName="monitor_screen_mat">
+    <Material
+        Name="monitor_screen_mat"
+        mapTo="monitor_screen_mat"
+        originalAssetName="monitor_base_mat">
+        <Material.Stages>
+            <Stages_beginarray
+                DiffuseMapAsset="@asset=Prototyping:ScreenTarget"
+                IgnoreLighting="true"/>
+            <Stages_beginarray
+                DiffuseColor="White"/>
+        </Material.Stages>
+    </Material>
+</MaterialAsset>

+ 6 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.asset.taml

@@ -0,0 +1,6 @@
+<ShapeAsset
+    AssetName="monitor_shape"
+    fileName="@assetFile=monitor_shape.fbx"
+    constuctorFileName="@assetFile=monitor_shape.tscript"
+    materialSlot0="@asset=Prototyping:monitor_base_mat"
+    materialSlot1="@asset=Prototyping:monitor_screen_mat"/>

BIN=BIN
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.fbx


+ 20 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.tscript

@@ -0,0 +1,20 @@
+
+singleton TSShapeConstructor(monitor_shapefbx)
+{
+   baseShapeAsset = "Prototyping:monitor_shape";
+   singleDetailSize = "0";
+   neverImportMat = "DefaultMaterial	ColorEffect*";
+   flipUVCoords = "0";
+   joinIdenticalVerts = "0";
+   reverseWindingOrder = "0";
+   removeRedundantMats = "0";
+   animFPS = "2";
+};
+
+function monitor_shapefbx::onLoad(%this)
+{
+   %this.addNode("Col-1", "", "0 0 0 0 0 1 0", "0", "");
+   %this.addNode("ColBox-1", "Col-1", "0 0 0 1 0 0 0", "0", "Bounds");
+   %this.addCollisionDetail("-1", "Box", "Bounds", "4", "10", "30", "32", "30", "30", "30", "Flood fill");
+   %this.setBounds("-0.8 -0.244957 -0.0409516 0.8 0.244957 1.10231");
+}

+ 2 - 2
Templates/BaseGame/game/data/UI/scripts/cursors.tscript

@@ -26,7 +26,7 @@ if($platform $= "macos")
    {
       hotSpot = "4 4";
       renderOffset = "0 0";
-      bitmapName = "data/ui/images/macCursor";
+      bitmapAsset = "UI:macCursor_image";
    };
 } 
 else 
@@ -35,6 +35,6 @@ else
    {
       hotSpot = "1 1";
       renderOffset = "0 0";
-      bitmapName = "data/ui/images/defaultCursor";
+      bitmapAsset = "UI:defaultCursor_image";
    };
 }

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

@@ -278,7 +278,7 @@ function AssetBrowser::initialize(%this)
       
    if(!isObject(%this.dirHandler))
    {
-      %this.dirHandler = makedirectoryHandler(%this-->filterTree, "cache,shaderCache", ""); 
+      %this.dirHandler = makedirectoryHandler(%this-->filterTree, "cache,shaderCache,previewCache", ""); 
       %this.dirHandler.currentAddress = "data/";
    }
       
@@ -1633,7 +1633,7 @@ function AssetBrowser::doRebuildAssetArray(%this)
             else
             {
                //got it.	
-               if(%folderName $= "shaderCache" || %folderName $= "cache" || %folderName $= ".git")
+               if(%folderName $= "shaderCache" || %folderName $= "cache" || %folderName $= ".git" || %folderName $= "previewCache")
                   continue;
                   
                if(!%this.coreModulesFilter && %folderName $= "core" && %breadcrumbPath $= "")

+ 28 - 4
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript

@@ -42,29 +42,53 @@ function ImageAsset::generatePreviewImage(%this, %previewButton, %forceRegenerat
    if(%forceRegenerate $= "")
       %forceRegenerate = false;
       
-   %previewPath = "tools/resources/previewCache/" @ %previewButton.moduleName @ "/";
+   %previewPath =  "tools/resources/previewCache/" @ %previewButton.moduleName @ "/";
    
    if(!IsDirectory(%previewPath))
    {
       $CurrentAssetBrowser.dirHandler.createFolder(%previewPath);
    }
    
-   %previewFilePath = %previewPath @ %this.assetName @ ".png";
+   %previewFilePath = %previewPath @ %this.assetName @ "_Preview.png";
    
    if(!isFile(%previewFilePath) || (compareFileTimes(%this.getImagePath(), %previewFilePath) == 1))
    {
       %generatePreview = true;
    }
 
+   %previewAssetName = "ToolsModule:" @ %this.assetName @ "_Preview";
+
    if(%generatePreview || %forceRegenerate)
    {
       %success = saveScaledImage(%this.getImagePath(), %previewFilePath, EditorSettings.value("Assets/Browser/PreviewImageSize"));
       
       if(%success)
-         %previewButton.setBitmap(%previewFilePath);
-      
+      {
+         
+         if(!AssetDatabase.isDeclaredAsset(%previewAssetName))
+         {
+            %preview_Asset = new ImageAsset()
+            {
+               assetName = %this.assetName @ "_Preview";
+               versionId = 1;
+               imageFile = "@" @ %this.assetName @ "_Preview.png";
+            };
+
+            TamlWrite(%preview_Asset, expandPath("^ToolsModule/resources/previewCache/" @ %previewButton.moduleName @ "/" @ %preview_Asset.AssetName @ ".asset.taml"));
+            %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1);
+            AssetDatabase.addDeclaredAsset(%toolsModuleDef, expandPath("^ToolsModule/resources/previewCache/" @ %previewButton.moduleName @ "/" @ %preview_Asset.AssetName @ ".asset.taml"));
+         }
+
+         %previewButton.bitmapAsset = %previewAssetName;
+      }
+
       return %success;
    }
+   else
+   {
+      %previewButton.bitmapAsset = %previewAssetName;
+      return true;
+   }
    
    return false;
 }

+ 28 - 7
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript

@@ -101,8 +101,7 @@ function MaterialAsset::generatePreviewImage(%this, %previewButton, %forceRegene
    if(%forceRegenerate $= "")
       %forceRegenerate = false;
       
-   %module = $CurrentAssetBrowser.dirHandler.getModuleFromAddress(makeRelativePath(filePath(AssetDatabase.getAssetFilePath(%this.getAssetId()))));
-   %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/";
+   %previewPath =  "tools/resources/previewCache/" @ %previewButton.moduleName @ "/";
 
    if(!IsDirectory(%previewPath))
    {
@@ -111,7 +110,8 @@ function MaterialAsset::generatePreviewImage(%this, %previewButton, %forceRegene
 
    %generatePreview = false;
 
-   %previewFilePath = %previewPath @ %this.assetName @ ".png";
+   %previewFilePath = %previewPath @ %this.assetName @ "_Preview.png";
+   
    if(!isFile(%previewFilePath))
    {
       %generatePreview = true;
@@ -126,6 +126,8 @@ function MaterialAsset::generatePreviewImage(%this, %previewButton, %forceRegene
       }
    }
 
+   %previewAssetName = "ToolsModule:" @ %this.assetName @ "_Preview";
+
    if(%generatePreview || %forceRegenerate)
    {
       if(isObject(%this.materialDefinitionName))
@@ -137,22 +139,41 @@ function MaterialAsset::generatePreviewImage(%this, %previewButton, %forceRegene
             %diffuseMapAsset = AssetDatabase.acquireAsset(%diffuseMapAssetId);
             AssetDatabase.releaseAsset(%diffuseMapAssetId);
          }
+
          %previewShapeDef = AssetDatabase.acquireAsset("ToolsModule:previewSphereShape");
          %generatedFilePath = %previewShapeDef.generateCachedPreviewImage(256, %this.materialDefinitionName);
       
          pathCopy(%generatedFilePath, %previewFilePath, false);
          fileDelete(%generatedFilePath);
 
-         if(isFile(%previewFilePath))
+         if(!AssetDatabase.isDeclaredAsset(%previewAssetName))
          {
-            %previewButton.setBitmap(%previewFilePath);
-            return true;
+            %preview_Asset = new ImageAsset()
+            {
+               assetName = %this.assetName @ "_Preview";
+               versionId = 1;
+               imageFile = "@" @ %this.assetName @ "_Preview.png";
+            };
+
+            TamlWrite(%preview_Asset, expandPath("^ToolsModule/resources/previewCache/" @ %previewButton.moduleName @ "/" @ %preview_Asset.AssetName @ ".asset.taml"));
+            %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1);
+            AssetDatabase.addDeclaredAsset(%toolsModuleDef, expandPath("^ToolsModule/resources/previewCache/" @ %previewButton.moduleName @ "/" @ %preview_Asset.AssetName @ ".asset.taml"));
          }
 
+         %previewButton.bitmapAsset = %previewAssetName;
+         return true;
+      }
+      else
+      {
          return false;
       }
    }
-      
+   else
+   {
+      %previewButton.bitmapAsset = %previewAssetName;
+      return true;
+   }
+   
    return false;
 }
 

+ 24 - 12
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript

@@ -111,23 +111,21 @@ function ShapeAsset::generatePreviewImage(%this, %previewButton, %forceRegenerat
    if(%forceRegenerate $= "")
       %forceRegenerate = false;
       
-   %assetId = %this.getAssetId();
-
-   %module = %previewButton.assetBrowser.dirHandler.getModuleFromAddress(makeRelativePath(filePath(%this.getShapePath())));
-   %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/";
+   %previewPath =  "tools/resources/previewCache/" @ %previewButton.moduleName @ "/";
    
    if(!IsDirectory(%previewPath))
    {
-      %previewButton.assetBrowser.dirHandler.createFolder(%previewPath);
+      $CurrentAssetBrowser.dirHandler.createFolder(%previewPath);
    }
    
-   %generatePreview = false;
+   %previewFilePath = %previewPath @ %this.assetName @ "_Preview.png";
    
-   %previewFilePath = %previewPath @ %this.assetName @ ".png";
    if(!isFile(%previewFilePath) || (compareFileTimes(%this.getShapePath(), %previewFilePath) == 1))
    {
       %generatePreview = true;
    }
+
+   %previewAssetName = "ToolsModule:" @ %this.assetName @ "_Preview";
    
    if(%generatePreview || %forceRegenerate)
    {
@@ -146,14 +144,28 @@ function ShapeAsset::generatePreviewImage(%this, %previewButton, %forceRegenerat
       
       pathCopy(%filePath, %previewFilePath, false);
       fileDelete(%filePath); //cleanup
-      
-      if(isFile(%previewFilePath))
+
+      if(!AssetDatabase.isDeclaredAsset(%previewAssetName))
       {
-         %previewButton.setBitmap(%previewFilePath);
-         return true;
+         %preview_Asset = new ImageAsset()
+         {
+            assetName = %this.assetName @ "_Preview";
+            versionId = 1;
+            imageFile = "@" @ %this.assetName @ "_Preview.png";
+         };
+
+         TamlWrite(%preview_Asset, expandPath("^ToolsModule/resources/previewCache/" @ %previewButton.moduleName @ "/" @ %preview_Asset.AssetName @ ".asset.taml"));
+         %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1);
+         AssetDatabase.addDeclaredAsset(%toolsModuleDef, expandPath("^ToolsModule/resources/previewCache/" @ %previewButton.moduleName @ "/" @ %preview_Asset.AssetName @ ".asset.taml"));
       }
 
-      return false;
+      %previewButton.bitmapAsset = %previewAssetName;
+      return true;
+   }
+   else
+   {
+      %previewButton.bitmapAsset = %previewAssetName;
+      return true;
    }
    
    return false;

+ 6 - 6
Templates/BaseGame/game/tools/gui/cursors.ed.tscript

@@ -24,40 +24,40 @@ new GuiCursor(LeftRightCursor)
 {
    hotSpot = "0.5 0";
    renderOffset = "0.5 0";
-   bitmapName = "./Images/leftRight";
+   bitmapAsset = "ToolsModule:leftRight_image";
 };
 
 new GuiCursor(UpDownCursor)
 {
    hotSpot = "1 1";
    renderOffset = "0 1";
-   bitmapName = "./Images/upDown";
+   bitmapAsset = "ToolsModule:upDown_image";
 };
 
 new GuiCursor(NWSECursor)
 {
    hotSpot = "1 1";
    renderOffset = "0.5 0.5";
-   bitmapName = "./Images/NWSE";
+   bitmapAsset = "ToolsModule:NWSE_image";
 };
 
 new GuiCursor(NESWCursor)
 {
    hotSpot = "1 1";
    renderOffset = "0.5 0.5";
-   bitmapName = "./Images/NESW";
+   bitmapAsset = "ToolsModule:NESW_image";
 };
 
 new GuiCursor(MoveCursor)
 {
    hotSpot = "1 1";
    renderOffset = "0.5 0.5";
-   bitmapName = "./Images/move";
+   bitmapAsset = "ToolsModule:move_image";
 };
 
 new GuiCursor(TextEditCursor)
 {
    hotSpot = "1 1";
    renderOffset = "0.5 0.5";
-   bitmapName = "./Images/textEdit";
+   bitmapAsset = "ToolsModule:textEdit_image";
 };

+ 8 - 8
Templates/BaseGame/game/tools/worldEditor/scripts/cursors.ed.tscript

@@ -27,48 +27,48 @@
 new GuiCursor(EditorHandCursor)
 {
    hotSpot = "7 0";
-   bitmapName = "~/worldEditor/images/CUR_hand.png";
+   bitmapAsset = "ToolsModule:CUR_hand_image";
 };
 
 new GuiCursor(EditorRotateCursor)
 {
    hotSpot = "11 18";
-   bitmapName = "~/worldEditor/images/CUR_rotate.png";
+   bitmapAsset = "ToolsModule:CUR_rotate_image";
 };
 
 new GuiCursor(EditorMoveCursor)
 {
    hotSpot = "9 13";
-   bitmapName = "~/worldEditor/images/CUR_grab.png";
+   bitmapAsset = "ToolsModule:CUR_grab_image";
 };
 
 new GuiCursor(EditorArrowCursor)
 {
    hotSpot = "0 0";
-   bitmapName = "~/worldEditor/images/CUR_3darrow.png";
+   bitmapAsset = "ToolsModule:CUR_3darrow_image";
 };
 
 new GuiCursor(EditorUpDownCursor)
 {
    hotSpot = "5 10";
-   bitmapName = "~/worldEditor/images/CUR_3dupdown";
+   bitmapAsset = "ToolsModule:CUR_3dupdown_image";
 };
 new GuiCursor(EditorLeftRightCursor)
 {
    hotSpot = "9 5";
-   bitmapName = "~/worldEditor/images/CUR_3dleftright";
+   bitmapAsset = "ToolsModule:CUR_3dleftright_image";
 };
 
 new GuiCursor(EditorDiagRightCursor)
 {
    hotSpot = "8 8";
-   bitmapName = "~/worldEditor/images/CUR_3ddiagright";
+   bitmapAsset = "ToolsModule:CUR_3ddiagright_image";
 };
 
 new GuiCursor(EditorDiagLeftCursor)
 {
    hotSpot = "8 8";
-   bitmapName = "~/worldEditor/images/CUR_3ddiagleft";
+   bitmapAsset = "ToolsModule:CUR_3ddiagleft_image";
 };
 
 new GuiControl(EmptyControl)