diff --git a/Engine/source/T3D/assets/ImageAsset.cpp b/Engine/source/T3D/assets/ImageAsset.cpp index 7e0cf1952..bc831a2c8 100644 --- a/Engine/source/T3D/assets/ImageAsset.cpp +++ b/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()) diff --git a/Engine/source/T3D/assets/ImageAsset.h b/Engine/source/T3D/assets/ImageAsset.h index 082ddb04f..102f59052 100644 --- a/Engine/source/T3D/assets/ImageAsset.h +++ b/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); static U32 getAssetById(String assetId, AssetPtr* 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 m##name##Asset;\ - String m##name##File;\ + AssetPtr 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 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 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 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); \ }; \ diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index eca044509..726f490de 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -2805,6 +2805,7 @@ void AssetImporter::acquireAssets(AssetImportObject* assetItem) if (AssetDatabase.isDeclaredAsset(assetId)) { AssetDatabase.acquireAsset(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; } diff --git a/Engine/source/T3D/fps/guiCrossHairHud.cpp b/Engine/source/T3D/fps/guiCrossHairHud.cpp index eaa318c53..052350be1 100644 --- a/Engine/source/T3D/fps/guiCrossHairHud.cpp +++ b/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(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(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 diff --git a/Engine/source/assets/assetBase.cpp b/Engine/source/assets/assetBase.cpp index dba9f142a..fcb9b5051 100644 --- a/Engine/source/assets/assetBase.cpp +++ b/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 { diff --git a/Engine/source/console/console.cpp b/Engine/source/console/console.cpp index eb967f35e..4b9316e6f 100644 --- a/Engine/source/console/console.cpp +++ b/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" diff --git a/Engine/source/gui/core/guiCanvas.cpp b/Engine/source/gui/core/guiCanvas.cpp index d00c3024a..c9f603d05 100644 --- a/Engine/source/gui/core/guiCanvas.cpp +++ b/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)) { diff --git a/Engine/source/gui/core/guiOffscreenCanvas.cpp b/Engine/source/gui/core/guiOffscreenCanvas.cpp index 522882b14..55562b028 100644 --- a/Engine/source/gui/core/guiOffscreenCanvas.cpp +++ b/Engine/source/gui/core/guiOffscreenCanvas.cpp @@ -9,6 +9,7 @@ IMPLEMENT_CONOBJECT(GuiOffscreenCanvas); +GuiOffscreenCanvas* GuiOffscreenCanvas::sActiveOffscreenCanvas = NULL; Vector 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(); } diff --git a/Engine/source/gui/core/guiOffscreenCanvas.h b/Engine/source/gui/core/guiOffscreenCanvas.h index 0d7a79d35..de8c221b8 100644 --- a/Engine/source/gui/core/guiOffscreenCanvas.h +++ b/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 sList; + static GuiOffscreenCanvas* sActiveOffscreenCanvas; }; #endif diff --git a/Engine/source/gui/core/guiTypes.cpp b/Engine/source/gui/core/guiTypes.cpp index 79d24b297..f0dbf8ebc 100644 --- a/Engine/source/gui/core/guiTypes.cpp +++ b/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(); diff --git a/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript b/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript index c053fd2cf..bd3841f9e 100644 --- a/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript +++ b/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 diff --git a/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/ScreenTarget.asset.taml b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/ScreenTarget.asset.taml new file mode 100644 index 000000000..fc9196375 --- /dev/null +++ b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/ScreenTarget.asset.taml @@ -0,0 +1,11 @@ + + + + + diff --git a/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_base_mat.asset.taml b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_base_mat.asset.taml new file mode 100644 index 000000000..6267d5871 --- /dev/null +++ b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_base_mat.asset.taml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_screen_mat.asset.taml b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_screen_mat.asset.taml new file mode 100644 index 000000000..db7490eea --- /dev/null +++ b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_screen_mat.asset.taml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.asset.taml b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.asset.taml new file mode 100644 index 000000000..1a8665bbd --- /dev/null +++ b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.asset.taml @@ -0,0 +1,6 @@ + diff --git a/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.fbx b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.fbx new file mode 100644 index 000000000..3acc77e04 Binary files /dev/null and b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.fbx differ diff --git a/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.tscript b/Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.tscript new file mode 100644 index 000000000..14e0fffea --- /dev/null +++ b/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"); +} diff --git a/Templates/BaseGame/game/data/UI/scripts/cursors.tscript b/Templates/BaseGame/game/data/UI/scripts/cursors.tscript index ba81636f7..ba54e5bed 100644 --- a/Templates/BaseGame/game/data/UI/scripts/cursors.tscript +++ b/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"; }; } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index 536ef79d5..37490772f 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/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 $= "") diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript index f571f2aa6..eb29fb365 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript +++ b/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; } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index eeb4fa1ef..6795387f4 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/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; } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript index 855ba712c..be6d0087e 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript +++ b/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; diff --git a/Templates/BaseGame/game/tools/gui/cursors.ed.tscript b/Templates/BaseGame/game/tools/gui/cursors.ed.tscript index 7e1ffbf7c..a4fff7628 100644 --- a/Templates/BaseGame/game/tools/gui/cursors.ed.tscript +++ b/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"; }; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/cursors.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/cursors.ed.tscript index f281b653a..2a7400884 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/cursors.ed.tscript +++ b/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)