diff --git a/Engine/lib/collada/src/dae/daeRawResolver.cpp b/Engine/lib/collada/src/dae/daeRawResolver.cpp index f297a36f4..b1ee18577 100644 --- a/Engine/lib/collada/src/dae/daeRawResolver.cpp +++ b/Engine/lib/collada/src/dae/daeRawResolver.cpp @@ -57,8 +57,11 @@ daeElement* daeRawResolver::resolveElement(const daeURI& uri) { daeElement *accessor; accessor = uri.getContainer(); - if ( accessor == NULL ) - return NULL; + if (accessor == NULL) + { + fclose(rawFile); + return NULL; + } src = accessor->getParentElement()->getParentElement(); daeElementRefArray children; accessor->getChildren( children ); diff --git a/Engine/lib/sdl/CMakeLists.txt b/Engine/lib/sdl/CMakeLists.txt index 54a23f0c7..ef82e73a0 100644 --- a/Engine/lib/sdl/CMakeLists.txt +++ b/Engine/lib/sdl/CMakeLists.txt @@ -1166,11 +1166,6 @@ elseif(WINDOWS) if(HAVE_DINPUT_H) set(SDL_JOYSTICK_DINPUT 1) list(APPEND EXTRA_LIBS dinput8) - if(CMAKE_COMPILER_IS_MINGW) - list(APPEND EXTRA_LIBS dxerr8) - elseif (NOT USE_WINSDK_DIRECTX) - list(APPEND EXTRA_LIBS dxerr) - endif() endif() if(HAVE_XINPUT_H) set(SDL_JOYSTICK_XINPUT 1) diff --git a/Engine/lib/sdl/configure.in b/Engine/lib/sdl/configure.in index 37c57e288..f38f02e34 100644 --- a/Engine/lib/sdl/configure.in +++ b/Engine/lib/sdl/configure.in @@ -3144,7 +3144,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau fi if test x$have_dinput = xyes; then AC_DEFINE(SDL_JOYSTICK_DINPUT, 1, [ ]) - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid" fi else AC_DEFINE(SDL_JOYSTICK_WINMM, 1, [ ]) diff --git a/Engine/source/T3D/assets/ComponentAsset.cpp b/Engine/source/T3D/assets/ComponentAsset.cpp index b329d391f..83045832e 100644 --- a/Engine/source/T3D/assets/ComponentAsset.cpp +++ b/Engine/source/T3D/assets/ComponentAsset.cpp @@ -74,7 +74,7 @@ ConsoleSetType(TypeComponentAssetPtr) if (pAssetPtr == NULL) { // No, so fail. - //Con::warnf("(TypeTextureAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + //Con::warnf("(TypeComponentAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); return; } @@ -85,24 +85,20 @@ ConsoleSetType(TypeComponentAssetPtr) } // Warn. - Con::warnf("(TypeTextureAssetPtr) - Cannot set multiple args to a single asset."); + Con::warnf("(TypeComponentAssetPtr) - Cannot set multiple args to a single asset."); } //----------------------------------------------------------------------------- -ComponentAsset::ComponentAsset() : - mpOwningAssetManager(NULL), - mAssetInitialized(false), - mAcquireReferenceCount(0) +ComponentAsset::ComponentAsset() { - // Generate an asset definition. - mpAssetDefinition = new AssetDefinition(); + mComponentName = StringTable->EmptyString(); + mComponentClass = StringTable->EmptyString(); + mFriendlyName = StringTable->EmptyString(); + mComponentType = StringTable->EmptyString(); + mDescription = StringTable->EmptyString(); - mComponentName = StringTable->lookup(""); - mComponentClass = StringTable->lookup(""); - mFriendlyName = StringTable->lookup(""); - mComponentType = StringTable->lookup(""); - mDescription = StringTable->lookup(""); + mScriptFile = StringTable->EmptyString(); } //----------------------------------------------------------------------------- @@ -127,6 +123,8 @@ void ComponentAsset::initPersistFields() addField("friendlyName", TypeString, Offset(mFriendlyName, ComponentAsset), "The human-readble name for the component."); addField("componentType", TypeString, Offset(mComponentType, ComponentAsset), "The category of the component for organizing in the editor."); addField("description", TypeString, Offset(mDescription, ComponentAsset), "Simple description of the component."); + + addField("scriptFile", TypeString, Offset(mScriptFile, ComponentAsset), "A script file with additional scripted functionality for this component."); } //------------------------------------------------------------------------------ @@ -135,4 +133,16 @@ void ComponentAsset::copyTo(SimObject* object) { // Call to parent. Parent::copyTo(object); +} + +void ComponentAsset::initializeAsset() +{ + if(Platform::isFile(mScriptFile)) + Con::executeFile(mScriptFile, false, false); +} + +void ComponentAsset::onAssetRefresh() +{ + if (Platform::isFile(mScriptFile)) + Con::executeFile(mScriptFile, false, false); } \ No newline at end of file diff --git a/Engine/source/T3D/assets/ComponentAsset.h b/Engine/source/T3D/assets/ComponentAsset.h index 1db53b8c8..9d803970b 100644 --- a/Engine/source/T3D/assets/ComponentAsset.h +++ b/Engine/source/T3D/assets/ComponentAsset.h @@ -44,17 +44,14 @@ class ComponentAsset : public AssetBase { typedef AssetBase Parent; - AssetManager* mpOwningAssetManager; - bool mAssetInitialized; - AssetDefinition* mpAssetDefinition; - U32 mAcquireReferenceCount; - StringTableEntry mComponentName; StringTableEntry mComponentClass; StringTableEntry mFriendlyName; StringTableEntry mComponentType; StringTableEntry mDescription; + StringTableEntry mScriptFile; + public: ComponentAsset(); virtual ~ComponentAsset(); @@ -69,12 +66,20 @@ public: StringTableEntry getComponentName() { return mComponentName; } StringTableEntry getComponentClass() { return mComponentClass; } StringTableEntry getFriendlyName() { return mFriendlyName; } - StringTableEntry getFriendlyType() { return mComponentType; } + StringTableEntry getComponentType() { return mComponentType; } StringTableEntry getDescription() { return mDescription; } + void setComponentName(StringTableEntry name) { mComponentName = name; } + void setComponentClass(StringTableEntry name) { mComponentClass = name; } + void setFriendlyName(StringTableEntry name) { mFriendlyName = name; } + void setComponentType(StringTableEntry typeName) { mComponentType = typeName; } + void setDescription(StringTableEntry description) { mDescription = description; } + + AssetDefinition* getAssetDefinition() { return mpAssetDefinition; } + protected: - virtual void initializeAsset(void) {} - virtual void onAssetRefresh(void) {} + virtual void initializeAsset(void); + virtual void onAssetRefresh(void); }; DefineConsoleType(TypeComponentAssetPtr, ComponentAsset) diff --git a/Engine/source/T3D/assets/ExampleAsset.cpp b/Engine/source/T3D/assets/ExampleAsset.cpp index eed7a4d19..b8c43ac07 100644 --- a/Engine/source/T3D/assets/ExampleAsset.cpp +++ b/Engine/source/T3D/assets/ExampleAsset.cpp @@ -74,7 +74,7 @@ ConsoleSetType(TypeExampleAssetPtr) if (pAssetPtr == NULL) { // No, so fail. - //Con::warnf("(TypeTextureAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + //Con::warnf("(TypeExampleAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); return; } @@ -85,18 +85,13 @@ ConsoleSetType(TypeExampleAssetPtr) } // Warn. - Con::warnf("(TypeTextureAssetPtr) - Cannot set multiple args to a single asset."); + Con::warnf("(TypeExampleAssetPtr) - Cannot set multiple args to a single asset."); } //----------------------------------------------------------------------------- -ExampleAsset::ExampleAsset() : -mpOwningAssetManager(NULL), -mAssetInitialized(false), -mAcquireReferenceCount(0) +ExampleAsset::ExampleAsset() { - // Generate an asset definition. - mpAssetDefinition = new AssetDefinition(); } //----------------------------------------------------------------------------- diff --git a/Engine/source/T3D/assets/ExampleAsset.h b/Engine/source/T3D/assets/ExampleAsset.h index 43532a6e5..b3a5a7695 100644 --- a/Engine/source/T3D/assets/ExampleAsset.h +++ b/Engine/source/T3D/assets/ExampleAsset.h @@ -43,11 +43,6 @@ class ExampleAsset : public AssetBase { typedef AssetBase Parent; - AssetManager* mpOwningAssetManager; - bool mAssetInitialized; - AssetDefinition* mpAssetDefinition; - U32 mAcquireReferenceCount; - public: ExampleAsset(); virtual ~ExampleAsset(); diff --git a/Engine/source/T3D/assets/GUIAsset.cpp b/Engine/source/T3D/assets/GUIAsset.cpp new file mode 100644 index 000000000..a011b56e3 --- /dev/null +++ b/Engine/source/T3D/assets/GUIAsset.cpp @@ -0,0 +1,222 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef GUI_ASSET_H +#include "GUIAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +// Debug Profiling. +#include "platform/profiler.h" + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(GUIAsset); + +ConsoleType(GUIAssetPtr, TypeGUIAssetPtr, GUIAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeGUIAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeGUIAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypeGUIAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeGUIAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +GUIAsset::GUIAsset() +{ + mScriptFilePath = StringTable->EmptyString(); + mGUIFilePath = StringTable->EmptyString(); +} + +//----------------------------------------------------------------------------- + +GUIAsset::~GUIAsset() +{ + // If the asset manager does not own the asset then we own the + // asset definition so delete it. + if (!getOwned()) + delete mpAssetDefinition; +} + +//----------------------------------------------------------------------------- + +void GUIAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addField("scriptFilePath", TypeString, Offset(mScriptFilePath, GUIAsset), "Path to the script file for the gui"); + addField("GUIFilePath", TypeString, Offset(mGUIFilePath, GUIAsset), "Path to the gui file"); +} + +//------------------------------------------------------------------------------ + +void GUIAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} + +void GUIAsset::initializeAsset() +{ + if (Platform::isFile(mGUIFilePath)) + Con::executeFile(mGUIFilePath, false, false); + + if (Platform::isFile(mScriptFilePath)) + Con::executeFile(mScriptFilePath, false, false); +} + +void GUIAsset::onAssetRefresh() +{ + if (Platform::isFile(mGUIFilePath)) + Con::executeFile(mGUIFilePath, false, false); + + if (Platform::isFile(mScriptFilePath)) + Con::executeFile(mScriptFilePath, false, false); +} + +//----------------------------------------------------------------------------- +// GuiInspectorTypeAssetId +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(GuiInspectorTypeGUIAssetPtr); + +ConsoleDocClass(GuiInspectorTypeGUIAssetPtr, + "@brief Inspector field type for GUI Asset Objects\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeGUIAssetPtr::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeGUIAssetPtr)->setInspectorFieldType("GuiInspectorTypeGUIAssetPtr"); +} + +GuiControl* GuiInspectorTypeGUIAssetPtr::constructEditControl() +{ + // Create base filename edit controls + GuiControl *retCtrl = Parent::constructEditControl(); + if (retCtrl == NULL) + return retCtrl; + + // Change filespec + char szBuffer[512]; + dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"GUIAsset\", \"AssetBrowser.changeAsset\", %d, %s);", + mInspector->getComponentGroupTargetId(), mCaption); + mBrowseButton->setField("Command", szBuffer); + + // Create "Open in ShapeEditor" button + mSMEdButton = new GuiBitmapButtonCtrl(); + + dSprintf(szBuffer, sizeof(szBuffer), "echo(\"Game Object Editor not implemented yet!\");", retCtrl->getId()); + mSMEdButton->setField("Command", szBuffer); + + char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor"; + mSMEdButton->setBitmap(bitmapName); + + mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); + mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mSMEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mSMEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the State Machine Editor"); + + mSMEdButton->registerObject(); + addObject(mSMEdButton); + + return retCtrl; +} + +bool GuiInspectorTypeGUIAssetPtr::updateRects() +{ + S32 dividerPos, dividerMargin; + mInspector->getDivider(dividerPos, dividerMargin); + Point2I fieldExtent = getExtent(); + Point2I fieldPos = getPosition(); + + mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y); + mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); + + bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + if (mBrowseButton != NULL) + { + mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); + resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); + } + + if (mSMEdButton != NULL) + { + RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); + resized |= mSMEdButton->resize(shapeEdRect.point, shapeEdRect.extent); + } + + return resized; +} \ No newline at end of file diff --git a/Engine/source/T3D/assets/GUIAsset.h b/Engine/source/T3D/assets/GUIAsset.h new file mode 100644 index 000000000..5668f9afd --- /dev/null +++ b/Engine/source/T3D/assets/GUIAsset.h @@ -0,0 +1,89 @@ +#pragma once +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#ifndef GUI_ASSET_H +#define GUI_ASSET_H + +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif + +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif + +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif + +#include "gui/editor/guiInspectorTypes.h" + +//----------------------------------------------------------------------------- +class GUIAsset : public AssetBase +{ + typedef AssetBase Parent; + + StringTableEntry mScriptFilePath; + StringTableEntry mGUIFilePath; + +public: + GUIAsset(); + virtual ~GUIAsset(); + + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); + + /// Declare Console Object. + DECLARE_CONOBJECT(GUIAsset); + +protected: + virtual void initializeAsset(void); + virtual void onAssetRefresh(void); +}; + +DefineConsoleType(TypeGUIAssetPtr, GUIAsset) + + +//----------------------------------------------------------------------------- +// TypeAssetId GuiInspectorField Class +//----------------------------------------------------------------------------- +class GuiInspectorTypeGUIAssetPtr : public GuiInspectorTypeFileName +{ + typedef GuiInspectorTypeFileName Parent; +public: + + GuiBitmapButtonCtrl *mSMEdButton; + + DECLARE_CONOBJECT(GuiInspectorTypeGUIAssetPtr); + static void consoleInit(); + + virtual GuiControl* constructEditControl(); + virtual bool updateRects(); +}; + +#endif // _ASSET_BASE_H_ + diff --git a/Engine/source/T3D/assets/GameObjectAsset.cpp b/Engine/source/T3D/assets/GameObjectAsset.cpp index 6659504bd..45b33b086 100644 --- a/Engine/source/T3D/assets/GameObjectAsset.cpp +++ b/Engine/source/T3D/assets/GameObjectAsset.cpp @@ -74,7 +74,7 @@ ConsoleSetType(TypeGameObjectAssetPtr) if (pAssetPtr == NULL) { // No, so fail. - //Con::warnf("(TypeTextureAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + //Con::warnf("(TypeGameObjectAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); return; } @@ -85,19 +85,13 @@ ConsoleSetType(TypeGameObjectAssetPtr) } // Warn. - Con::warnf("(TypeTextureAssetPtr) - Cannot set multiple args to a single asset."); + Con::warnf("(TypeGameObjectAssetPtr) - Cannot set multiple args to a single asset."); } //----------------------------------------------------------------------------- -GameObjectAsset::GameObjectAsset() : - mpOwningAssetManager(NULL), - mAssetInitialized(false), - mAcquireReferenceCount(0) +GameObjectAsset::GameObjectAsset() { - // Generate an asset definition. - mpAssetDefinition = new AssetDefinition(); - mGameObjectName = StringTable->lookup(""); mScriptFilePath = StringTable->lookup(""); mTAMLFilePath = StringTable->lookup(""); @@ -131,4 +125,94 @@ void GameObjectAsset::copyTo(SimObject* object) { // Call to parent. Parent::copyTo(object); +} + +void GameObjectAsset::initializeAsset() +{ + if (Platform::isFile(mScriptFilePath)) + Con::executeFile(mScriptFilePath, false, false); +} + +void GameObjectAsset::onAssetRefresh() +{ + if (Platform::isFile(mScriptFilePath)) + Con::executeFile(mScriptFilePath, false, false); +} + +//----------------------------------------------------------------------------- +// GuiInspectorTypeAssetId +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(GuiInspectorTypeGameObjectAssetPtr); + +ConsoleDocClass(GuiInspectorTypeGameObjectAssetPtr, + "@brief Inspector field type for Game Objects\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeGameObjectAssetPtr::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeGameObjectAssetPtr)->setInspectorFieldType("GuiInspectorTypeGameObjectAssetPtr"); +} + +GuiControl* GuiInspectorTypeGameObjectAssetPtr::constructEditControl() +{ + // Create base filename edit controls + GuiControl *retCtrl = Parent::constructEditControl(); + if (retCtrl == NULL) + return retCtrl; + + // Change filespec + char szBuffer[512]; + dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"GameObjectAsset\", \"AssetBrowser.changeAsset\", %d, %s);", + mInspector->getComponentGroupTargetId(), mCaption); + mBrowseButton->setField("Command", szBuffer); + + // Create "Open in ShapeEditor" button + mSMEdButton = new GuiBitmapButtonCtrl(); + + dSprintf(szBuffer, sizeof(szBuffer), "echo(\"Game Object Editor not implemented yet!\");", retCtrl->getId()); + mSMEdButton->setField("Command", szBuffer); + + char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor"; + mSMEdButton->setBitmap(bitmapName); + + mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); + mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mSMEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mSMEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the State Machine Editor"); + + mSMEdButton->registerObject(); + addObject(mSMEdButton); + + return retCtrl; +} + +bool GuiInspectorTypeGameObjectAssetPtr::updateRects() +{ + S32 dividerPos, dividerMargin; + mInspector->getDivider(dividerPos, dividerMargin); + Point2I fieldExtent = getExtent(); + Point2I fieldPos = getPosition(); + + mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y); + mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); + + bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + if (mBrowseButton != NULL) + { + mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); + resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); + } + + if (mSMEdButton != NULL) + { + RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); + resized |= mSMEdButton->resize(shapeEdRect.point, shapeEdRect.extent); + } + + return resized; } \ No newline at end of file diff --git a/Engine/source/T3D/assets/GameObjectAsset.h b/Engine/source/T3D/assets/GameObjectAsset.h index 82230cd5c..954a11300 100644 --- a/Engine/source/T3D/assets/GameObjectAsset.h +++ b/Engine/source/T3D/assets/GameObjectAsset.h @@ -38,17 +38,15 @@ #ifndef _ASSET_FIELD_TYPES_H_ #include "assets/assetFieldTypes.h" #endif +#ifndef _GUI_INSPECTOR_TYPES_H_ +#include "gui/editor/guiInspectorTypes.h" +#endif //----------------------------------------------------------------------------- class GameObjectAsset : public AssetBase { typedef AssetBase Parent; - AssetManager* mpOwningAssetManager; - bool mAssetInitialized; - AssetDefinition* mpAssetDefinition; - U32 mAcquireReferenceCount; - StringTableEntry mGameObjectName; StringTableEntry mScriptFilePath; StringTableEntry mTAMLFilePath; @@ -65,11 +63,29 @@ public: DECLARE_CONOBJECT(GameObjectAsset); protected: - virtual void initializeAsset(void) {} - virtual void onAssetRefresh(void) {} + virtual void initializeAsset(void); + virtual void onAssetRefresh(void); }; DefineConsoleType(TypeGameObjectAssetPtr, GameObjectAsset) + +//----------------------------------------------------------------------------- +// TypeAssetId GuiInspectorField Class +//----------------------------------------------------------------------------- +class GuiInspectorTypeGameObjectAssetPtr : public GuiInspectorTypeFileName +{ + typedef GuiInspectorTypeFileName Parent; +public: + + GuiBitmapButtonCtrl *mSMEdButton; + + DECLARE_CONOBJECT(GuiInspectorTypeGameObjectAssetPtr); + static void consoleInit(); + + virtual GuiControl* constructEditControl(); + virtual bool updateRects(); +}; + #endif // _ASSET_BASE_H_ diff --git a/Engine/source/T3D/assets/ImageAsset.cpp b/Engine/source/T3D/assets/ImageAsset.cpp new file mode 100644 index 000000000..ff4c3ac70 --- /dev/null +++ b/Engine/source/T3D/assets/ImageAsset.cpp @@ -0,0 +1,156 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef IMAGE_ASSET_H +#include "ImageAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +// Debug Profiling. +#include "platform/profiler.h" + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(ImageAsset); + +ConsoleType(ImageAssetPtr, TypeImageAssetPtr, ImageAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeImageAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeImageAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypeImageAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeImageAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +ImageAsset::ImageAsset() : AssetBase(), mImage(nullptr), mUseMips(true), mIsHDRImage(false), mIsValidImage(false) +{ + mImageFileName = StringTable->EmptyString(); +} + +//----------------------------------------------------------------------------- + +ImageAsset::~ImageAsset() +{ +} + +//----------------------------------------------------------------------------- + +void ImageAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addField("imageFile", TypeString, Offset(mImageFileName, ImageAsset), "Path to the image file."); + addField("useMips", TypeBool, Offset(mUseMips, ImageAsset), "Should the image use mips? (Currently unused)."); + addField("isHDRImage", TypeBool, Offset(mIsHDRImage, ImageAsset), "Is the image in an HDR format? (Currently unused)"); +} + +//------------------------------------------------------------------------------ + +void ImageAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} + +void ImageAsset::loadImage() +{ + SAFE_DELETE(mImage); + + if (mImageFileName) + { + if (!Platform::isFile(mImageFileName)) + { + Con::errorf("ImageAsset::initializeAsset: Attempted to load file %s but it was not valid!", mImageFileName); + return; + } + + mImage.set(mImageFileName, &GFXStaticTextureSRGBProfile, avar("%s() - mImage (line %d)", __FUNCTION__, __LINE__)); + + if (mImage) + { + mIsValidImage = true; + return; + } + } + + mIsValidImage = false; +} + +void ImageAsset::initializeAsset() +{ + loadImage(); +} + +void ImageAsset::onAssetRefresh() +{ + loadImage(); +} \ No newline at end of file diff --git a/Engine/source/T3D/assets/ImageAsset.h b/Engine/source/T3D/assets/ImageAsset.h new file mode 100644 index 000000000..f5b52db07 --- /dev/null +++ b/Engine/source/T3D/assets/ImageAsset.h @@ -0,0 +1,85 @@ +#pragma once +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#ifndef IMAGE_ASSET_H +#define IMAGE_ASSET_H + +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif + +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif + +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif + +#include "gfx/bitmap/gBitmap.h" +#include "gfx/gfxTextureHandle.h" + +//----------------------------------------------------------------------------- +class ImageAsset : public AssetBase +{ + typedef AssetBase Parent; + + StringTableEntry mImageFileName; + + GFXTexHandle mImage; + + bool mIsValidImage; + bool mUseMips; + bool mIsHDRImage; + +public: + ImageAsset(); + virtual ~ImageAsset(); + + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); + + /// Declare Console Object. + DECLARE_CONOBJECT(ImageAsset); + + StringTableEntry getImageFileName() { return mImageFileName; } + + bool isValid() { return mIsValidImage; } + + GFXTexHandle* getImage() { return &mImage; } + +protected: + virtual void initializeAsset(void); + virtual void onAssetRefresh(void); + + void loadImage(); +}; + +DefineConsoleType(TypeImageAssetPtr, ImageAsset) + +#endif + diff --git a/Engine/source/T3D/assets/LevelAsset.cpp b/Engine/source/T3D/assets/LevelAsset.cpp new file mode 100644 index 000000000..34084924a --- /dev/null +++ b/Engine/source/T3D/assets/LevelAsset.cpp @@ -0,0 +1,128 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef LEVEL_ASSET_H +#include "LevelAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +// Debug Profiling. +#include "platform/profiler.h" + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(LevelAsset); + +ConsoleType(LevelAssetPtr, TypeLevelAssetPtr, LevelAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeLevelAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeLevelAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypeLevelAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeLevelAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false) +{ + mLevelFile = StringTable->EmptyString(); + mPreviewImage = StringTable->EmptyString(); + + mMainLevelAsset = StringTable->EmptyString(); +} + +//----------------------------------------------------------------------------- + +LevelAsset::~LevelAsset() +{ + // If the asset manager does not own the asset then we own the + // asset definition so delete it. + if (!getOwned()) + delete mpAssetDefinition; +} + +//----------------------------------------------------------------------------- + +void LevelAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addField("LevelFile", TypeString, Offset(mLevelFile, LevelAsset), "Path to the actual level file."); + addField("PreviewImage", TypeString, Offset(mPreviewImage, LevelAsset), "Path to the image used for selection preview."); +} + +//------------------------------------------------------------------------------ + +void LevelAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} \ No newline at end of file diff --git a/Engine/source/T3D/assets/LevelAsset.h b/Engine/source/T3D/assets/LevelAsset.h new file mode 100644 index 000000000..3fc58c183 --- /dev/null +++ b/Engine/source/T3D/assets/LevelAsset.h @@ -0,0 +1,72 @@ +#pragma once +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#ifndef LEVEL_ASSET_H +#define LEVEL_ASSET_H + +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif + +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif + +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif + +//----------------------------------------------------------------------------- +class LevelAsset : public AssetBase +{ + typedef AssetBase Parent; + + StringTableEntry mLevelFile; + StringTableEntry mPreviewImage; + + bool mIsSubLevel; + StringTableEntry mMainLevelAsset; + +public: + LevelAsset(); + virtual ~LevelAsset(); + + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); + + /// Declare Console Object. + DECLARE_CONOBJECT(LevelAsset); + +protected: + virtual void initializeAsset(void) {} + virtual void onAssetRefresh(void) {} +}; + +DefineConsoleType(TypeLevelAssetPtr, LevelAsset) + +#endif // _ASSET_BASE_H_ + diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp new file mode 100644 index 000000000..697f21e37 --- /dev/null +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -0,0 +1,241 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef MATERIALASSET_H +#include "MaterialAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(MaterialAsset); + +ConsoleType(MaterialAssetPtr, TypeMaterialAssetPtr, MaterialAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeMaterialAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeMaterialAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypeMaterialAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeMaterialAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +MaterialAsset::MaterialAsset() +{ + mShaderGraphFile = ""; + mScriptFile = ""; + mMatDefinitionName = ""; +} + +//----------------------------------------------------------------------------- + +MaterialAsset::~MaterialAsset() +{ + // If the asset manager does not own the asset then we own the + // asset definition so delete it. + if (!getOwned()) + delete mpAssetDefinition; +} + +//----------------------------------------------------------------------------- + +void MaterialAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + //addField("shaderGraph", TypeRealString, Offset(mShaderGraphFile, MaterialAsset), ""); + addField("scriptFile", TypeRealString, Offset(mScriptFile, MaterialAsset), "Path to the file containing the material definition."); + addField("materialDefinitionName", TypeRealString, Offset(mMatDefinitionName, MaterialAsset), "Name of the material definition this asset is for."); +} + +void MaterialAsset::initializeAsset() +{ + // Call parent. + Parent::initializeAsset(); + + compileShader(); + + if (Platform::isFile(mScriptFile)) + Con::executeFile(mScriptFile, false, false); +} + +void MaterialAsset::onAssetRefresh() +{ + if (Platform::isFile(mScriptFile)) + Con::executeFile(mScriptFile, false, false); + + if (!mMatDefinitionName.isEmpty()) + { + Material* matDef; + if (!Sim::findObject(mMatDefinitionName.c_str(), matDef)) + { + Con::errorf("MaterialAsset: Unable to find the Material %s", mMatDefinitionName.c_str()); + return; + } + + matDef->reload(); + } +} + +//------------------------------------------------------------------------------ + +void MaterialAsset::compileShader() +{ +} + +void MaterialAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} + +ConsoleMethod(MaterialAsset, compileShader, void, 2, 2, "() - Compiles the material's generated shader, if any. Not yet implemented\n") +{ + object->compileShader(); +} + +//----------------------------------------------------------------------------- +// GuiInspectorTypeAssetId +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(GuiInspectorTypeMaterialAssetPtr); + +ConsoleDocClass(GuiInspectorTypeMaterialAssetPtr, + "@brief Inspector field type for Material Asset Objects\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeMaterialAssetPtr::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeMaterialAssetPtr)->setInspectorFieldType("GuiInspectorTypeMaterialAssetPtr"); +} + +GuiControl* GuiInspectorTypeMaterialAssetPtr::constructEditControl() +{ + // Create base filename edit controls + GuiControl *retCtrl = Parent::constructEditControl(); + if (retCtrl == NULL) + return retCtrl; + + // Change filespec + char szBuffer[512]; + dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"MaterialAsset\", \"AssetBrowser.changeAsset\", %d, %s);", + mInspector->getComponentGroupTargetId(), mCaption); + mBrowseButton->setField("Command", szBuffer); + + // Create "Open in ShapeEditor" button + mSMEdButton = new GuiBitmapButtonCtrl(); + + dSprintf(szBuffer, sizeof(szBuffer), "echo(\"Game Object Editor not implemented yet!\");", retCtrl->getId()); + mSMEdButton->setField("Command", szBuffer); + + char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor"; + mSMEdButton->setBitmap(bitmapName); + + mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); + mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mSMEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mSMEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the Material Editor"); + + mSMEdButton->registerObject(); + addObject(mSMEdButton); + + return retCtrl; +} + +bool GuiInspectorTypeMaterialAssetPtr::updateRects() +{ + S32 dividerPos, dividerMargin; + mInspector->getDivider(dividerPos, dividerMargin); + Point2I fieldExtent = getExtent(); + Point2I fieldPos = getPosition(); + + mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y); + mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); + + bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + if (mBrowseButton != NULL) + { + mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); + resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); + } + + if (mSMEdButton != NULL) + { + RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); + resized |= mSMEdButton->resize(shapeEdRect.point, shapeEdRect.extent); + } + + return resized; +} \ No newline at end of file diff --git a/Engine/source/T3D/assets/MaterialAsset.h b/Engine/source/T3D/assets/MaterialAsset.h new file mode 100644 index 000000000..2cb9f15b1 --- /dev/null +++ b/Engine/source/T3D/assets/MaterialAsset.h @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#ifndef MATERIALASSET_H +#define MATERIALASSET_H + +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif + +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif + +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif + +#ifndef _GFXDEVICE_H_ +#include "gfx/gfxDevice.h" +#endif + +#ifndef _GUI_INSPECTOR_TYPES_H_ +#include "gui/editor/guiInspectorTypes.h" +#endif + +#include "materials/matTextureTarget.h" +#include "materials/materialDefinition.h" +#include "materials/customMaterialDefinition.h" + +//----------------------------------------------------------------------------- +class MaterialAsset : public AssetBase +{ + typedef AssetBase Parent; + + String mShaderGraphFile; + String mScriptFile; + String mMatDefinitionName; + +public: + MaterialAsset(); + virtual ~MaterialAsset(); + + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); + + virtual void initializeAsset(); + virtual void onAssetRefresh(void); + + void compileShader(); + + String getMaterialDefinitionName() { return mMatDefinitionName; } + + /// Declare Console Object. + DECLARE_CONOBJECT(MaterialAsset); +}; + +DefineConsoleType(TypeMaterialAssetPtr, MaterialAsset) + +//----------------------------------------------------------------------------- +// TypeAssetId GuiInspectorField Class +//----------------------------------------------------------------------------- +class GuiInspectorTypeMaterialAssetPtr : public GuiInspectorTypeFileName +{ + typedef GuiInspectorTypeFileName Parent; +public: + + GuiBitmapButtonCtrl *mSMEdButton; + + DECLARE_CONOBJECT(GuiInspectorTypeMaterialAssetPtr); + static void consoleInit(); + + virtual GuiControl* constructEditControl(); + virtual bool updateRects(); +}; + +#endif // _ASSET_BASE_H_ + diff --git a/Engine/source/T3D/assets/ParticleAsset.cpp b/Engine/source/T3D/assets/ParticleAsset.cpp new file mode 100644 index 000000000..bcefd2dfa --- /dev/null +++ b/Engine/source/T3D/assets/ParticleAsset.cpp @@ -0,0 +1,205 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef PARTICLE_ASSET_H +#include "ParticleAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +// Debug Profiling. +#include "platform/profiler.h" + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(ParticleAsset); + +ConsoleType(ParticleAssetPtr, TypeParticleAssetPtr, ParticleAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeParticleAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeParticleAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypeParticleAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeParticleAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +ParticleAsset::ParticleAsset() +{ + mScriptFilePath = StringTable->EmptyString(); + mDatablockFilePath = StringTable->EmptyString(); +} + +//----------------------------------------------------------------------------- + +ParticleAsset::~ParticleAsset() +{ + // If the asset manager does not own the asset then we own the + // asset definition so delete it. + if (!getOwned()) + delete mpAssetDefinition; +} + +//----------------------------------------------------------------------------- + +void ParticleAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addField("scriptFilePath", TypeString, Offset(mScriptFilePath, ParticleAsset), "Path to the script file for the particle effect"); + addField("DatablockFilePath", TypeString, Offset(mDatablockFilePath, ParticleAsset), "Path to the datablock file"); +} + +//------------------------------------------------------------------------------ + +void ParticleAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} + + +//----------------------------------------------------------------------------- +// GuiInspectorTypeAssetId +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(GuiInspectorTypeParticleAssetPtr); + +ConsoleDocClass(GuiInspectorTypeParticleAssetPtr, + "@brief Inspector field type for Partial Asset Objects\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeParticleAssetPtr::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeParticleAssetPtr)->setInspectorFieldType("GuiInspectorTypeParticleAssetPtr"); +} + +GuiControl* GuiInspectorTypeParticleAssetPtr::constructEditControl() +{ + // Create base filename edit controls + GuiControl *retCtrl = Parent::constructEditControl(); + if (retCtrl == NULL) + return retCtrl; + + // Change filespec + char szBuffer[512]; + dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"ParticleAsset\", \"AssetBrowser.changeAsset\", %d, %s);", + mInspector->getComponentGroupTargetId(), mCaption); + mBrowseButton->setField("Command", szBuffer); + + // Create "Open in ShapeEditor" button + mSMEdButton = new GuiBitmapButtonCtrl(); + + dSprintf(szBuffer, sizeof(szBuffer), "echo(\"Game Object Editor not implemented yet!\");", retCtrl->getId()); + mSMEdButton->setField("Command", szBuffer); + + char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor"; + mSMEdButton->setBitmap(bitmapName); + + mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); + mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mSMEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mSMEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the State Machine Editor"); + + mSMEdButton->registerObject(); + addObject(mSMEdButton); + + return retCtrl; +} + +bool GuiInspectorTypeParticleAssetPtr::updateRects() +{ + S32 dividerPos, dividerMargin; + mInspector->getDivider(dividerPos, dividerMargin); + Point2I fieldExtent = getExtent(); + Point2I fieldPos = getPosition(); + + mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y); + mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); + + bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + if (mBrowseButton != NULL) + { + mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); + resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); + } + + if (mSMEdButton != NULL) + { + RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); + resized |= mSMEdButton->resize(shapeEdRect.point, shapeEdRect.extent); + } + + return resized; +} \ No newline at end of file diff --git a/Engine/source/T3D/assets/ParticleAsset.h b/Engine/source/T3D/assets/ParticleAsset.h new file mode 100644 index 000000000..b446c2cf0 --- /dev/null +++ b/Engine/source/T3D/assets/ParticleAsset.h @@ -0,0 +1,89 @@ +#pragma once +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#ifndef PARTICLE_ASSET_H +#define PARTICLE_ASSET_H + +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif + +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif + +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif + +#include "gui/editor/guiInspectorTypes.h" + +//----------------------------------------------------------------------------- +class ParticleAsset : public AssetBase +{ + typedef AssetBase Parent; + + StringTableEntry mScriptFilePath; + StringTableEntry mDatablockFilePath; + +public: + ParticleAsset(); + virtual ~ParticleAsset(); + + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); + + /// Declare Console Object. + DECLARE_CONOBJECT(ParticleAsset); + +protected: + virtual void initializeAsset(void) {} + virtual void onAssetRefresh(void) {} +}; + +DefineConsoleType(TypeParticleAssetPtr, ParticleAsset) + + +//----------------------------------------------------------------------------- +// TypeAssetId GuiInspectorField Class +//----------------------------------------------------------------------------- +class GuiInspectorTypeParticleAssetPtr : public GuiInspectorTypeFileName +{ + typedef GuiInspectorTypeFileName Parent; +public: + + GuiBitmapButtonCtrl *mSMEdButton; + + DECLARE_CONOBJECT(GuiInspectorTypeParticleAssetPtr); + static void consoleInit(); + + virtual GuiControl* constructEditControl(); + virtual bool updateRects(); +}; + +#endif // _ASSET_BASE_H_ + diff --git a/Engine/source/T3D/assets/PostEffectAsset.cpp b/Engine/source/T3D/assets/PostEffectAsset.cpp new file mode 100644 index 000000000..4eb67a6a3 --- /dev/null +++ b/Engine/source/T3D/assets/PostEffectAsset.cpp @@ -0,0 +1,129 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef POSTEFFECT_ASSET_H +#include "PostEffectAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +// Debug Profiling. +#include "platform/profiler.h" + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(PostEffectAsset); + +ConsoleType(PostEffectAssetPtr, TypePostEffectAssetPtr, PostEffectAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypePostEffectAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypePostEffectAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypePostEffectAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypePostEffectAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +PostEffectAsset::PostEffectAsset() +{ + mScriptFile = StringTable->EmptyString(); +} + +//----------------------------------------------------------------------------- + +PostEffectAsset::~PostEffectAsset() +{ + // If the asset manager does not own the asset then we own the + // asset definition so delete it. + if (!getOwned()) + delete mpAssetDefinition; +} + +//----------------------------------------------------------------------------- + +void PostEffectAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addField("scriptFile", TypeString, Offset(mScriptFile, PostEffectAsset), "Path to the script file."); +} + +//------------------------------------------------------------------------------ + +void PostEffectAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} + +void PostEffectAsset::initializeAsset() +{ + //mPostEffect = new PostEffect(); +} \ No newline at end of file diff --git a/Engine/source/platform/menus/menuBar.h b/Engine/source/T3D/assets/PostEffectAsset.h similarity index 50% rename from Engine/source/platform/menus/menuBar.h rename to Engine/source/T3D/assets/PostEffectAsset.h index 0e0e64602..381fa1576 100644 --- a/Engine/source/platform/menus/menuBar.h +++ b/Engine/source/T3D/assets/PostEffectAsset.h @@ -1,5 +1,6 @@ +#pragma once //----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC +// Copyright (c) 2013 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -19,53 +20,52 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#ifndef POSTEFFECT_ASSET_H +#define POSTEFFECT_ASSET_H -#include "console/simBase.h" +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif -#ifndef _MENUBAR_H_ -#define _MENUBAR_H_ +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif -// Forward Refs -class PlatformMenuBarData; -class PopupMenu; -class GuiCanvas; +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif -class MenuBar : public SimSet +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif + +#include "postFx/postEffect.h" + +//----------------------------------------------------------------------------- +class PostEffectAsset : public AssetBase { - typedef SimSet Parent; + typedef AssetBase Parent; -protected: - PlatformMenuBarData *mData; - GuiCanvas *mCanvas; - - /// Update the native menu bar to ensure consistency with the set - void updateMenuBar(PopupMenu *menu = NULL); - - void createPlatformPopupMenuData(); - void deletePlatformPopupMenuData(); + StringTableEntry mScriptFile; public: - MenuBar(); - virtual ~MenuBar(); - DECLARE_CONOBJECT(MenuBar); + PostEffectAsset(); + virtual ~PostEffectAsset(); - /// Attach this menu bar to the native menu bar - void attachToCanvas(GuiCanvas *owner, S32 pos); - /// Remove this menu bar from the native menu bar - void removeFromCanvas(); + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); - /// Returns true if this menu is attached to the menu bar - bool isAttachedToCanvas() { return mCanvas != NULL; } + virtual void initializeAsset(); - virtual void insertObject(SimObject *obj, S32 pos); + /// Declare Console Object. + DECLARE_CONOBJECT(PostEffectAsset); - // Overridden SimSet methods to ensure menu bar consistency when attached - virtual void addObject(SimObject *obj); - virtual void removeObject(SimObject *obj); - virtual void pushObject(SimObject *obj); - virtual void popObject(); - - virtual bool reOrder(SimObject *obj, SimObject *target = 0); +protected: + virtual void onAssetRefresh(void) {} }; -#endif // _MENUBAR_H_ +DefineConsoleType(TypePostEffectAssetPtr, PostEffectAsset) + +#endif // _ASSET_BASE_H_ + diff --git a/Engine/source/T3D/assets/ScriptAsset.cpp b/Engine/source/T3D/assets/ScriptAsset.cpp new file mode 100644 index 000000000..10c3be777 --- /dev/null +++ b/Engine/source/T3D/assets/ScriptAsset.cpp @@ -0,0 +1,137 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#ifndef SCRIPT_ASSET_H +#include "ScriptAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +// Debug Profiling. +#include "platform/profiler.h" + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(ScriptAsset); + +ConsoleType(ScriptAssetPtr, TypeScriptAssetPtr, ScriptAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeScriptAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeScriptAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypeScriptAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeScriptAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +ScriptAsset::ScriptAsset() : AssetBase(), mIsServerSide(true) +{ + mScriptFilePath = StringTable->EmptyString(); +} + +//----------------------------------------------------------------------------- + +ScriptAsset::~ScriptAsset() +{ + // If the asset manager does not own the asset then we own the + // asset definition so delete it. + if (!getOwned()) + delete mpAssetDefinition; +} + +//----------------------------------------------------------------------------- + +void ScriptAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addField("scriptFilePath", TypeString, Offset(mScriptFilePath, ScriptAsset), "Path to the script file."); + addField("isServerSide", TypeBool, Offset(mIsServerSide, ScriptAsset), "Is this script file to be run on the server side?"); + +} + +//------------------------------------------------------------------------------ + +void ScriptAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} + +void ScriptAsset::initializeAsset() +{ + if (Platform::isFile(mScriptFilePath)) + Con::executeFile(mScriptFilePath, false, false); +} + +void ScriptAsset::onAssetRefresh() +{ + if (Platform::isFile(mScriptFilePath)) + Con::executeFile(mScriptFilePath, false, false); +} \ No newline at end of file diff --git a/Engine/source/platformSDL/menus/guiPlatformGenericMenuBar.h b/Engine/source/T3D/assets/ScriptAsset.h similarity index 56% rename from Engine/source/platformSDL/menus/guiPlatformGenericMenuBar.h rename to Engine/source/T3D/assets/ScriptAsset.h index b2129a8b1..8c12f2b88 100644 --- a/Engine/source/platformSDL/menus/guiPlatformGenericMenuBar.h +++ b/Engine/source/T3D/assets/ScriptAsset.h @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC +// Copyright (c) 2013 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -19,33 +19,51 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- - +#ifndef SCRIPT_ASSET_H +#define SCRIPT_ASSET_H #pragma once -#include "gui/editor/guiMenuBar.h" -#include "platformSDL/menus/PlatformSDLPopupMenuData.h" -#include "platform/menus/popupMenu.h" +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif -class GuiPlatformGenericMenuBar : public GuiMenuBar +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif + +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif + +//----------------------------------------------------------------------------- +class ScriptAsset : public AssetBase { - typedef GuiMenuBar Parent; + typedef AssetBase Parent; + + StringTableEntry mScriptFilePath; + bool mIsServerSide; + public: - DECLARE_CONOBJECT(GuiPlatformGenericMenuBar); + ScriptAsset(); + virtual ~ScriptAsset(); - virtual void menuItemSelected(Menu *menu, MenuItem *item) - { - AssertFatal(menu && item, ""); + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); - PopupMenu *popupMenu = PlatformPopupMenuData::mMenuMap[menu]; - AssertFatal(popupMenu, ""); - - popupMenu->handleSelect(item->id); - - Parent::menuItemSelected(menu, item); - } + /// Declare Console Object. + DECLARE_CONOBJECT(ScriptAsset); protected: - /// menu id / item id - Map, String> mCmds; + virtual void initializeAsset(void); + virtual void onAssetRefresh(void); +}; + +DefineConsoleType(TypeScriptAssetPtr, ScriptAsset) + +#endif // _ASSET_BASE_H_ -}; \ No newline at end of file diff --git a/Engine/source/T3D/assets/ShapeAnimationAsset.cpp b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp new file mode 100644 index 000000000..4c2b0283e --- /dev/null +++ b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp @@ -0,0 +1,175 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef SHAPE_ANIMATION_ASSET_H +#include "ShapeAnimationAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +#include "core/resourceManager.h" + +// Debug Profiling. +#include "platform/profiler.h" + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(ShapeAnimationAsset); + +ConsoleType(ShapeAnimationAssetPtr, TypeShapeAnimationAssetPtr, ShapeAnimationAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeShapeAnimationAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeShapeAnimationAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypeShapeAnimationAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeShapeAnimationAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +ShapeAnimationAsset::ShapeAnimationAsset() : + mIsEmbedded(false), mIsCyclical(true), mIsBlend(false), mBlendFrame(0), mStartFrame(0), mEndFrame(-1), mPadRotation(true), mPadTransforms(false) +{ + mFileName = StringTable->EmptyString(); + mAnimationName = StringTable->EmptyString(); + + mBlendAnimAssetName = StringTable->EmptyString(); +} + +//----------------------------------------------------------------------------- + +ShapeAnimationAsset::~ShapeAnimationAsset() +{ + // If the asset manager does not own the asset then we own the + // asset definition so delete it. + if (!getOwned()) + delete mpAssetDefinition; +} + +//----------------------------------------------------------------------------- + +void ShapeAnimationAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addField("animationFile", TypeFilename, Offset(mFileName, ShapeAnimationAsset), "Path to the file name containing the animation"); + addField("animationName", TypeString, Offset(mAnimationName, ShapeAnimationAsset), "Name of the animation"); + + addField("isEmbedded", TypeBool, Offset(mIsEmbedded, ShapeAnimationAsset), "If true, this animation asset just referrs to an embedded animation of a regular shape mesh. If false, it is a self-contained animation file"); + + addField("isCyclic", TypeBool, Offset(mIsCyclical, ShapeAnimationAsset), "Is this animation looping?"); + + addField("isBlend", TypeBool, Offset(mIsBlend, ShapeAnimationAsset), "Is this animation blended with another?"); + addField("blendRefAnimation", TypeString, Offset(mBlendAnimAssetName, ShapeAnimationAsset), "AssetID of the animation to reference for our blending"); + addField("blendFrame", TypeS32, Offset(mBlendFrame, ShapeAnimationAsset), "Which frame of the reference animation do we use for our blending"); + + addField("startFrame", TypeS32, Offset(mStartFrame, ShapeAnimationAsset), "What frame does this animation clip start on"); + addField("endFrame", TypeS32, Offset(mEndFrame, ShapeAnimationAsset), "What fram does this animation clip end on"); + addField("padRotation", TypeBool, Offset(mPadRotation, ShapeAnimationAsset), "Are the rotation values padded"); + addField("padTransforms", TypeBool, Offset(mPadTransforms, ShapeAnimationAsset), "Are the transform values padded"); +} + +//------------------------------------------------------------------------------ + +void ShapeAnimationAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} + +void ShapeAnimationAsset::initializeAsset(void) +{ + if (!mIsEmbedded) + { + //If we're not embedded, we need to load in our initial shape and do some prepwork + + char filenameBuf[1024]; + Con::expandScriptFilename(filenameBuf, sizeof(filenameBuf), mFileName); + + mSourceShape = ResourceManager::get().load(filenameBuf); + + if (!mSourceShape->addSequence("ambient", "", mAnimationName, mStartFrame, mEndFrame, mPadRotation, mPadTransforms)) + { + Con::errorf("ShapeAnimationAsset::initializeAsset - Unable to do initial setup of the animation clip named %s for asset %s", mAnimationName, getAssetName()); + return; + } + + S32 sequenceId = mSourceShape->findSequence(mAnimationName); + + if(mIsCyclical) + mSourceShape->sequences[sequenceId].flags |= TSShape::Cyclic; + else + mSourceShape->sequences[sequenceId].flags &= (~(TSShape::Cyclic)); + } +} + +void ShapeAnimationAsset::onAssetRefresh(void) +{ + +} \ No newline at end of file diff --git a/Engine/source/T3D/assets/ShapeAnimationAsset.h b/Engine/source/T3D/assets/ShapeAnimationAsset.h new file mode 100644 index 000000000..0b7bf1790 --- /dev/null +++ b/Engine/source/T3D/assets/ShapeAnimationAsset.h @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#ifndef SHAPE_ANIMATION_ASSET_H +#define SHAPE_ANIMATION_ASSET_H + +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif + +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif + +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif +#ifndef _TSSHAPE_H_ +#include "ts/tsShape.h" +#endif +#ifndef __RESOURCE_H__ +#include "core/resource.h" +#endif + +//----------------------------------------------------------------------------- +class ShapeAnimationAsset : public AssetBase +{ + typedef AssetBase Parent; + +protected: + StringTableEntry mFileName; + + bool mIsEmbedded; + bool mIsCyclical; + + bool mIsBlend; + + StringTableEntry mBlendAnimAssetName; + + S32 mBlendFrame; + + // + StringTableEntry mAnimationName; + S32 mStartFrame; + S32 mEndFrame; + bool mPadRotation; + bool mPadTransforms; + + Resource mSourceShape; + +public: + ShapeAnimationAsset(); + virtual ~ShapeAnimationAsset(); + + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); + + /// Declare Console Object. + DECLARE_CONOBJECT(ShapeAnimationAsset); + +protected: + virtual void initializeAsset(void); + virtual void onAssetRefresh(void); + +public: + StringTableEntry getAnimationFilename() { return mFileName; } + StringTableEntry getAnimationName() { return mAnimationName; } + StringTableEntry getBlendAnimationName() { return mBlendAnimAssetName; } + + S32 getStartFrame() { return mStartFrame; } + S32 getEndFrame() { return mEndFrame; } + + bool getPadRotation() { return mPadRotation; } + bool getPadTransforms() { return mPadTransforms; } + + bool isEmbedded() { return mIsEmbedded; } + bool isCyclic() { return mIsCyclical; } + bool isBlend() { return mIsBlend; } + + S32 getBlendFrame() { return mBlendFrame; } +}; + +DefineConsoleType(TypeShapeAnimationAssetPtr, ShapeAnimationAsset) + +//----------------------------------------------------------------------------- +// TypeAssetId GuiInspectorField Class +//----------------------------------------------------------------------------- +/*class GuiInspectorTypeShapeAnimationAssetPtr : public GuiInspectorTypeFileName +{ + typedef GuiInspectorTypeFileName Parent; +public: + + GuiBitmapButtonCtrl *mShapeEdButton; + + DECLARE_CONOBJECT(GuiInspectorTypeShapeAnimationAssetPtr); + static void consoleInit(); + + virtual GuiControl* constructEditControl(); + virtual bool updateRects(); +};*/ + +#endif // _ASSET_BASE_H_ + diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index d8cbce453..2bce369ea 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -49,14 +49,14 @@ IMPLEMENT_CONOBJECT(ShapeAsset); -ConsoleType(TestAssetPtr, TypeShapeAssetPtr, ShapeAsset, ASSET_ID_FIELD_PREFIX) +ConsoleType(assetIdString, TypeShapeAssetPtr, String, ASSET_ID_FIELD_PREFIX) //----------------------------------------------------------------------------- ConsoleGetType(TypeShapeAssetPtr) { // Fetch asset Id. - return (*((AssetPtr*)dptr)).getAssetId(); + return *((StringTableEntry*)dptr); } //----------------------------------------------------------------------------- @@ -69,33 +69,22 @@ ConsoleSetType(TypeShapeAssetPtr) // Yes, so fetch field value. const char* pFieldValue = argv[0]; - // Fetch asset pointer. - AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + // Fetch asset Id. + StringTableEntry* assetId = (StringTableEntry*)(dptr); - // Is the asset pointer the correct type? - if (pAssetPtr == NULL) - { - // No, so fail. - //Con::warnf("(TypeTextureAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); - return; - } - - // Set asset. - pAssetPtr->setAssetId(pFieldValue); + // Update asset value. + *assetId = StringTable->insert(pFieldValue); return; } // Warn. - Con::warnf("(TypeTextureAssetPtr) - Cannot set multiple args to a single asset."); + Con::warnf("(TypeAssetId) - Cannot set multiple args to a single asset."); } //----------------------------------------------------------------------------- -ShapeAsset::ShapeAsset() : -mpOwningAssetManager(NULL), -mAssetInitialized(false), -mAcquireReferenceCount(0) +ShapeAsset::ShapeAsset() { } @@ -116,7 +105,21 @@ void ShapeAsset::initPersistFields() // Call parent. Parent::initPersistFields(); - addField("fileName", TypeFilename, Offset(mFileName, ShapeAsset), "Path to the script file we want to execute"); + addField("fileName", TypeFilename, Offset(mFileName, ShapeAsset), "Path to the shape file we want to render"); +} + +void ShapeAsset::setDataField(StringTableEntry slotName, const char *array, const char *value) +{ + Parent::setDataField(slotName, array, value); + + //Now, if it's a material slot of some fashion, set it up + StringTableEntry matSlotName = StringTable->insert("materialAsset"); + if (String(slotName).startsWith(matSlotName)) + { + StringTableEntry matId = StringTable->insert(value); + + mMaterialAssetIds.push_back(matId); + } } void ShapeAsset::initializeAsset() @@ -132,6 +135,45 @@ void ShapeAsset::initializeAsset() bool ShapeAsset::loadShape() { + mMaterialAssets.clear(); + mMaterialAssetIds.clear(); + + //First, load any material, animation, etc assets we may be referencing in our asset + // Find any asset dependencies. + AssetManager::typeAssetDependsOnHash::Iterator assetDependenciesItr = mpOwningAssetManager->getDependedOnAssets()->find(mpAssetDefinition->mAssetId); + + // Does the asset have any dependencies? + if (assetDependenciesItr != mpOwningAssetManager->getDependedOnAssets()->end()) + { + // Iterate all dependencies. + while (assetDependenciesItr != mpOwningAssetManager->getDependedOnAssets()->end() && assetDependenciesItr->key == mpAssetDefinition->mAssetId) + { + StringTableEntry assetType = mpOwningAssetManager->getAssetType(assetDependenciesItr->value); + + if (assetType == StringTable->insert("MaterialAsset")) + { + mMaterialAssetIds.push_back(assetDependenciesItr->value); + + //Force the asset to become initialized if it hasn't been already + AssetPtr matAsset = assetDependenciesItr->value; + + mMaterialAssets.push_back(matAsset); + } + else if (assetType == StringTable->insert("ShapeAnimationAsset")) + { + mAnimationAssetIds.push_back(assetDependenciesItr->value); + + //Force the asset to become initialized if it hasn't been already + AssetPtr animAsset = assetDependenciesItr->value; + + mAnimationAssets.push_back(animAsset); + } + + // Next dependency. + assetDependenciesItr++; + } + } + mShape = ResourceManager::get().load(mFileName); if (!mShape) @@ -140,6 +182,51 @@ bool ShapeAsset::loadShape() return false; //if it failed to load, bail out } + bool hasBlends = false; + + //Now that we've successfully loaded our shape and have any materials and animations loaded + //we need to set up the animations we're using on our shape + for (S32 i = mAnimationAssets.size()-1; i >= 0; --i) + { + String srcName = mAnimationAssets[i]->getAnimationName(); + String srcPath(mAnimationAssets[i]->getAnimationFilename()); + //SplitSequencePathAndName(srcPath, srcName); + + if (!mShape->addSequence(srcPath, srcName, srcName, + mAnimationAssets[i]->getStartFrame(), mAnimationAssets[i]->getEndFrame(), mAnimationAssets[i]->getPadRotation(), mAnimationAssets[i]->getPadTransforms())) + return false; + + if (mAnimationAssets[i]->isBlend()) + hasBlends = true; + } + + //if any of our animations are blends, set those up now + if (hasBlends) + { + for (U32 i=0; i < mAnimationAssets.size(); ++i) + { + if (mAnimationAssets[i]->isBlend() && mAnimationAssets[i]->getBlendAnimationName() != StringTable->EmptyString()) + { + //gotta do a bit of logic here. + //First, we need to make sure the anim asset we depend on for our blend is loaded + AssetPtr blendAnimAsset = mAnimationAssets[i]->getBlendAnimationName(); + + if (blendAnimAsset.isNull()) + { + Con::errorf("ShapeAsset::initializeAsset - Unable to acquire reference animation asset %s for asset %s to blend!", mAnimationAssets[i]->getBlendAnimationName(), mAnimationAssets[i]->getAssetName()); + return false; + } + + String refAnimName = blendAnimAsset->getAnimationName(); + if (!mShape->setSequenceBlend(mAnimationAssets[i]->getAnimationName(), true, blendAnimAsset->getAnimationName(), mAnimationAssets[i]->getBlendFrame())) + { + Con::errorf("ShapeAnimationAsset::initializeAsset - Unable to set animation clip %s for asset %s to blend!", mAnimationAssets[i]->getAnimationName(), mAnimationAssets[i]->getAssetName()); + return false; + } + } + } + } + return true; } @@ -153,4 +240,141 @@ void ShapeAsset::copyTo(SimObject* object) void ShapeAsset::onAssetRefresh(void) { + if (dStrcmp(mFileName, "") == 0) + return; + + loadShape(); +} + +void ShapeAsset::SplitSequencePathAndName(String& srcPath, String& srcName) +{ + srcName = ""; + + // Determine if there is a sequence name at the end of the source string, and + // if so, split the filename from the sequence name + S32 split = srcPath.find(' ', 0, String::Right); + S32 split2 = srcPath.find('\t', 0, String::Right); + if ((split == String::NPos) || (split2 > split)) + split = split2; + if (split != String::NPos) + { + split2 = split + 1; + while ((srcPath[split2] != '\0') && dIsspace(srcPath[split2])) + split2++; + + // now 'split' is at the end of the path, and 'split2' is at the start of the sequence name + srcName = srcPath.substr(split2); + srcPath = srcPath.erase(split, srcPath.length() - split); + } +} + +ShapeAnimationAsset* ShapeAsset::getAnimation(S32 index) +{ + if (index < mAnimationAssets.size()) + { + return mAnimationAssets[index]; + } + + return nullptr; +} + +DefineEngineMethod(ShapeAsset, getMaterialCount, S32, (), , + "Gets the number of materials for this shape asset.\n" + "@return Material count.\n") +{ + return object->getMaterialCount(); +} + +DefineEngineMethod(ShapeAsset, getAnimationCount, S32, (), , + "Gets the number of animations for this shape asset.\n" + "@return Animation count.\n") +{ + return object->getAnimationCount(); +} + +DefineEngineMethod(ShapeAsset, getAnimation, ShapeAnimationAsset*, (S32 index), (0), + "Gets a particular shape animation asset for this shape.\n" + "@param animation asset index.\n" + "@return Shape Animation Asset.\n") +{ + return object->getAnimation(index); +} +//----------------------------------------------------------------------------- +// GuiInspectorTypeAssetId +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(GuiInspectorTypeShapeAssetPtr); + +ConsoleDocClass(GuiInspectorTypeShapeAssetPtr, + "@brief Inspector field type for Shapes\n\n" + "Editor use only.\n\n" + "@internal" + ); + +void GuiInspectorTypeShapeAssetPtr::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeShapeAssetPtr)->setInspectorFieldType("GuiInspectorTypeShapeAssetPtr"); +} + +GuiControl* GuiInspectorTypeShapeAssetPtr::constructEditControl() +{ + // Create base filename edit controls + GuiControl *retCtrl = Parent::constructEditControl(); + if (retCtrl == NULL) + return retCtrl; + + // Change filespec + char szBuffer[512]; + dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"ShapeAsset\", \"AssetBrowser.changeAsset\", %d, %s);", + mInspector->getComponentGroupTargetId(), mCaption); + mBrowseButton->setField("Command", szBuffer); + + setDataField(StringTable->insert("ComponentOwner"), NULL, String::ToString(mInspector->getComponentGroupTargetId()).c_str()); + + // Create "Open in ShapeEditor" button + mShapeEdButton = new GuiBitmapButtonCtrl(); + + dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.openShapeAsset(%d.getText());", retCtrl->getId()); + mShapeEdButton->setField("Command", szBuffer); + + char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor"; + mShapeEdButton->setBitmap(bitmapName); + + mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); + mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mShapeEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mShapeEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the Shape Editor"); + + mShapeEdButton->registerObject(); + addObject(mShapeEdButton); + + return retCtrl; +} + +bool GuiInspectorTypeShapeAssetPtr::updateRects() +{ + S32 dividerPos, dividerMargin; + mInspector->getDivider(dividerPos, dividerMargin); + Point2I fieldExtent = getExtent(); + Point2I fieldPos = getPosition(); + + mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y); + mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); + + bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + if (mBrowseButton != NULL) + { + mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); + resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); + } + + if (mShapeEdButton != NULL) + { + RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); + resized |= mShapeEdButton->resize(shapeEdRect.point, shapeEdRect.extent); + } + + return resized; } \ No newline at end of file diff --git a/Engine/source/T3D/assets/ShapeAsset.h b/Engine/source/T3D/assets/ShapeAsset.h index d727d0a1c..45fca7e86 100644 --- a/Engine/source/T3D/assets/ShapeAsset.h +++ b/Engine/source/T3D/assets/ShapeAsset.h @@ -44,21 +44,35 @@ #ifndef __RESOURCE_H__ #include "core/resource.h" #endif +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif +#ifndef MATERIALASSET_H +#include "MaterialAsset.h" +#endif +#ifndef SHAPE_ANIMATION_ASSET_H +#include "ShapeAnimationAsset.h" +#endif + +#include "gui/editor/guiInspectorTypes.h" //----------------------------------------------------------------------------- class ShapeAsset : public AssetBase { typedef AssetBase Parent; - AssetManager* mpOwningAssetManager; - bool mAssetInitialized; - AssetDefinition* mpAssetDefinition; - U32 mAcquireReferenceCount; - protected: StringTableEntry mFileName; Resource mShape; + //Material assets we're dependent on and use + Vector mMaterialAssetIds; + Vector> mMaterialAssets; + + //Animation assets we're dependent on and use + Vector mAnimationAssetIds; + Vector> mAnimationAssets; + public: ShapeAsset(); virtual ~ShapeAsset(); @@ -67,6 +81,8 @@ public: static void initPersistFields(); virtual void copyTo(SimObject* object); + virtual void setDataField(StringTableEntry slotName, const char *array, const char *value); + virtual void initializeAsset(); /// Declare Console Object. @@ -78,11 +94,37 @@ public: Resource getShapeResource() { return mShape; } + void SplitSequencePathAndName(String& srcPath, String& srcName); + String getShapeFilename() { return mFileName; } + + U32 getShapeFilenameHash() { return _StringTable::hashString(mFileName); } + + S32 getMaterialCount() { return mMaterialAssets.size(); } + S32 getAnimationCount() { return mAnimationAssets.size(); } + ShapeAnimationAsset* getAnimation(S32 index); + protected: virtual void onAssetRefresh(void); }; -DefineConsoleType(TypeShapeAssetPtr, ShapeAsset) +DefineConsoleType(TypeShapeAssetPtr, S32) + +//----------------------------------------------------------------------------- +// TypeAssetId GuiInspectorField Class +//----------------------------------------------------------------------------- +class GuiInspectorTypeShapeAssetPtr : public GuiInspectorTypeFileName +{ + typedef GuiInspectorTypeFileName Parent; +public: + + GuiBitmapButtonCtrl *mShapeEdButton; + + DECLARE_CONOBJECT(GuiInspectorTypeShapeAssetPtr); + static void consoleInit(); + + virtual GuiControl* constructEditControl(); + virtual bool updateRects(); +}; #endif diff --git a/Engine/source/T3D/assets/SoundAsset.cpp b/Engine/source/T3D/assets/SoundAsset.cpp new file mode 100644 index 000000000..f2978aa38 --- /dev/null +++ b/Engine/source/T3D/assets/SoundAsset.cpp @@ -0,0 +1,141 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef SOUND_ASSET_H +#include "SoundAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +// Debug Profiling. +#include "platform/profiler.h" + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(SoundAsset); + +ConsoleType(SoundAssetPtr, TypeSoundAssetPtr, SoundAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeSoundAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeSoundAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypeSoundAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeSoundAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +SoundAsset::SoundAsset() +{ + mSoundFilePath = StringTable->EmptyString(); + + mPitchAdjust = 0; + mVolumeAdjust = 0; + + //mSound = nullptr; +} + +//----------------------------------------------------------------------------- + +SoundAsset::~SoundAsset() +{ + // If the asset manager does not own the asset then we own the + // asset definition so delete it. + if (!getOwned()) + delete mpAssetDefinition; +} + +//----------------------------------------------------------------------------- + +void SoundAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addField("soundFilePath", TypeFilename, Offset(mSoundFilePath, SoundAsset), "Path to the sound file."); + + addField("pitchAdjust", TypeF32, Offset(mPitchAdjust, SoundAsset), "Adjustment of the pitch value"); + addField("volumeAdjust", TypeF32, Offset(mVolumeAdjust, SoundAsset), "Adjustment to the volume."); +} + +//------------------------------------------------------------------------------ + +void SoundAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} + +void SoundAsset::initializeAsset(void) +{ +} + +void SoundAsset::onAssetRefresh(void) +{ + +} \ No newline at end of file diff --git a/Engine/source/T3D/assets/SoundAsset.h b/Engine/source/T3D/assets/SoundAsset.h new file mode 100644 index 000000000..bfe582823 --- /dev/null +++ b/Engine/source/T3D/assets/SoundAsset.h @@ -0,0 +1,75 @@ +#pragma once +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#ifndef SOUND_ASSET_H +#define SOUND_ASSET_H + +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif + +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif + +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif + +class SFXTrack; + +//----------------------------------------------------------------------------- +class SoundAsset : public AssetBase +{ + typedef AssetBase Parent; + +protected: + StringTableEntry mSoundFilePath; + F32 mPitchAdjust; + F32 mVolumeAdjust; + +public: + SoundAsset(); + virtual ~SoundAsset(); + + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); + + /// Declare Console Object. + DECLARE_CONOBJECT(SoundAsset); + + StringTableEntry getSoundFilePath() { return mSoundFilePath; } + +protected: + virtual void initializeAsset(void); + virtual void onAssetRefresh(void); +}; + +DefineConsoleType(TypeSoundAssetPtr, SoundAsset) + +#endif // _ASSET_BASE_H_ + diff --git a/Engine/source/T3D/assets/stateMachineAsset.cpp b/Engine/source/T3D/assets/stateMachineAsset.cpp new file mode 100644 index 000000000..99ba956a4 --- /dev/null +++ b/Engine/source/T3D/assets/stateMachineAsset.cpp @@ -0,0 +1,207 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef STATE_MACHINE_ASSET_H +#include "stateMachineAsset.h" +#endif + +#ifndef _ASSET_MANAGER_H_ +#include "assets/assetManager.h" +#endif + +#ifndef _CONSOLETYPES_H_ +#include "console/consoleTypes.h" +#endif + +#ifndef _TAML_ +#include "persistence/taml/taml.h" +#endif + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +// Debug Profiling. +#include "platform/profiler.h" + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(StateMachineAsset); + +ConsoleType(StateMachineAssetPtr, TypeStateMachineAssetPtr, StateMachineAsset, ASSET_ID_FIELD_PREFIX) + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeStateMachineAssetPtr) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeStateMachineAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + // No, so fail. + //Con::warnf("(TypeStateMachineAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeStateMachineAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- + +StateMachineAsset::StateMachineAsset() +{ + mStateMachineFileName = StringTable->EmptyString(); +} + +//----------------------------------------------------------------------------- + +StateMachineAsset::~StateMachineAsset() +{ + // If the asset manager does not own the asset then we own the + // asset definition so delete it. + if (!getOwned()) + delete mpAssetDefinition; +} + +//----------------------------------------------------------------------------- + +void StateMachineAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addField("stateMachineFile", TypeString, Offset(mStateMachineFileName, StateMachineAsset), "Path to the state machine file."); +} + +//------------------------------------------------------------------------------ + +void StateMachineAsset::copyTo(SimObject* object) +{ + // Call to parent. + Parent::copyTo(object); +} + +DefineEngineMethod(StateMachineAsset, notifyAssetChanged, void, (),,"") +{ + ResourceManager::get().getChangedSignal().trigger(object->getStateMachineFileName()); +} + +//----------------------------------------------------------------------------- +// GuiInspectorTypeAssetId +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(GuiInspectorTypeStateMachineAssetPtr); + +ConsoleDocClass(GuiInspectorTypeStateMachineAssetPtr, + "@brief Inspector field type for State Machines\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeStateMachineAssetPtr::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeStateMachineAssetPtr)->setInspectorFieldType("GuiInspectorTypeStateMachineAssetPtr"); +} + +GuiControl* GuiInspectorTypeStateMachineAssetPtr::constructEditControl() +{ + // Create base filename edit controls + GuiControl *retCtrl = Parent::constructEditControl(); + if (retCtrl == NULL) + return retCtrl; + + // Change filespec + char szBuffer[512]; + dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"StateMachineAsset\", \"AssetBrowser.changeAsset\", %d, %s);", + mInspector->getComponentGroupTargetId(), mCaption); + mBrowseButton->setField("Command", szBuffer); + + // Create "Open in ShapeEditor" button + mSMEdButton = new GuiBitmapButtonCtrl(); + + dSprintf(szBuffer, sizeof(szBuffer), "StateMachineEditor.loadStateMachineAsset(%d.getText()); Canvas.pushDialog(StateMachineEditor);", retCtrl->getId()); + mSMEdButton->setField("Command", szBuffer); + + char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor"; + mSMEdButton->setBitmap(bitmapName); + + mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); + mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mSMEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mSMEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the State Machine Editor"); + + mSMEdButton->registerObject(); + addObject(mSMEdButton); + + return retCtrl; +} + +bool GuiInspectorTypeStateMachineAssetPtr::updateRects() +{ + S32 dividerPos, dividerMargin; + mInspector->getDivider(dividerPos, dividerMargin); + Point2I fieldExtent = getExtent(); + Point2I fieldPos = getPosition(); + + mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y); + mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); + + bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + if (mBrowseButton != NULL) + { + mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); + resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); + } + + if (mSMEdButton != NULL) + { + RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); + resized |= mSMEdButton->resize(shapeEdRect.point, shapeEdRect.extent); + } + + return resized; +} \ No newline at end of file diff --git a/Engine/source/T3D/assets/stateMachineAsset.h b/Engine/source/T3D/assets/stateMachineAsset.h new file mode 100644 index 000000000..6452a6e6f --- /dev/null +++ b/Engine/source/T3D/assets/stateMachineAsset.h @@ -0,0 +1,89 @@ +#pragma once +//----------------------------------------------------------------------------- +// Copyright (c) 2013 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#ifndef STATE_MACHINE_ASSET_H +#define STATE_MACHINE_ASSET_H + +#ifndef _ASSET_BASE_H_ +#include "assets/assetBase.h" +#endif + +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _STRINGUNIT_H_ +#include "string/stringUnit.h" +#endif + +#ifndef _ASSET_FIELD_TYPES_H_ +#include "assets/assetFieldTypes.h" +#endif + +#include "gui/editor/guiInspectorTypes.h" + +//----------------------------------------------------------------------------- +class StateMachineAsset : public AssetBase +{ + typedef AssetBase Parent; + + StringTableEntry mStateMachineFileName; + +public: + StateMachineAsset(); + virtual ~StateMachineAsset(); + + /// Engine. + static void initPersistFields(); + virtual void copyTo(SimObject* object); + + /// Declare Console Object. + DECLARE_CONOBJECT(StateMachineAsset); + + StringTableEntry getStateMachineFileName() { return mStateMachineFileName; } + +protected: + virtual void initializeAsset(void) {} + virtual void onAssetRefresh(void) {} +}; + +DefineConsoleType(TypeStateMachineAssetPtr, StateMachineAsset) + +//----------------------------------------------------------------------------- +// TypeAssetId GuiInspectorField Class +//----------------------------------------------------------------------------- +class GuiInspectorTypeStateMachineAssetPtr : public GuiInspectorTypeFileName +{ + typedef GuiInspectorTypeFileName Parent; +public: + + GuiBitmapButtonCtrl *mSMEdButton; + + DECLARE_CONOBJECT(GuiInspectorTypeStateMachineAssetPtr); + static void consoleInit(); + + virtual GuiControl* constructEditControl(); + virtual bool updateRects(); +}; + +#endif + diff --git a/Engine/source/T3D/components/animation/animationComponent.cpp b/Engine/source/T3D/components/animation/animationComponent.cpp index e1a71511c..42871259d 100644 --- a/Engine/source/T3D/components/animation/animationComponent.cpp +++ b/Engine/source/T3D/components/animation/animationComponent.cpp @@ -72,7 +72,6 @@ IMPLEMENT_CALLBACK(AnimationComponent, onAnimationTrigger, void, (Component* obj AnimationComponent::AnimationComponent() : Component() { mNetworked = true; - mNetFlags.set(Ghostable | ScopeAlways); mFriendlyName = "Animation(Component)"; mComponentType = "Render"; @@ -223,29 +222,17 @@ U32 AnimationComponent::packUpdate(NetConnection *con, U32 mask, BitStream *stre { U32 retMask = Parent::packUpdate(con, mask, stream); - //early test if we lack an owner, ghost-wise - //no point in trying, just re-queue the mask and go - if (!mOwner || con->getGhostIndex(mOwner) == -1) + for (int i = 0; i < MaxScriptThreads; i++) { - stream->writeFlag(false); - return retMask |= ThreadMask; - } - else - { - stream->writeFlag(true); - - for (int i = 0; i < MaxScriptThreads; i++) + Thread& st = mAnimationThreads[i]; + if (stream->writeFlag((st.sequence != -1 || st.state == Thread::Destroy) && (mask & (ThreadMaskN << i)))) { - Thread& st = mAnimationThreads[i]; - if (stream->writeFlag( (st.sequence != -1 || st.state == Thread::Destroy) && (mask & (ThreadMaskN << i)) ) ) - { - stream->writeInt(st.sequence,ThreadSequenceBits); - stream->writeInt(st.state,2); - stream->write(st.timescale); - stream->write(st.position); - stream->writeFlag(st.atEnd); - stream->writeFlag(st.transition); - } + stream->writeInt(st.sequence, ThreadSequenceBits); + stream->writeInt(st.state, 2); + stream->write(st.timescale); + stream->write(st.position); + stream->writeFlag(st.atEnd); + stream->writeFlag(st.transition); } } @@ -256,29 +243,26 @@ void AnimationComponent::unpackUpdate(NetConnection *con, BitStream *stream) { Parent::unpackUpdate(con, stream); - if (stream->readFlag()) + for (S32 i = 0; i < MaxScriptThreads; i++) { - for (S32 i = 0; i < MaxScriptThreads; i++) + if (stream->readFlag()) { - if (stream->readFlag()) - { - Thread& st = mAnimationThreads[i]; - U32 seq = stream->readInt(ThreadSequenceBits); - st.state = stream->readInt(2); - stream->read( &st.timescale ); - stream->read( &st.position ); - st.atEnd = stream->readFlag(); - bool transition = stream->readFlag(); + Thread& st = mAnimationThreads[i]; + U32 seq = stream->readInt(ThreadSequenceBits); + st.state = stream->readInt(2); + stream->read( &st.timescale ); + stream->read( &st.position ); + st.atEnd = stream->readFlag(); + bool transition = stream->readFlag(); - if (!st.thread || st.sequence != seq && st.state != Thread::Destroy) - setThreadSequence(i, seq, false, transition); - else - updateThread(st); - - } + if (!st.thread || st.sequence != seq && st.state != Thread::Destroy) + setThreadSequence(i, seq, false, transition); + else + updateThread(st); } } } + void AnimationComponent::processTick() { Parent::processTick(); @@ -327,9 +311,6 @@ const char *AnimationComponent::getThreadSequenceName(U32 slot) bool AnimationComponent::setThreadSequence(U32 slot, S32 seq, bool reset, bool transition, F32 transTime) { - if (!mOwnerShapeInstance) - return false; - Thread& st = mAnimationThreads[slot]; if (st.thread && st.sequence == seq && st.state == Thread::Play && !reset) return true; @@ -340,7 +321,6 @@ bool AnimationComponent::setThreadSequence(U32 slot, S32 seq, bool reset, bool t if (seq < MaxSequenceIndex) { - setMaskBits(-1); setMaskBits(ThreadMaskN << slot); st.sequence = seq; st.transition = transition; @@ -633,6 +613,9 @@ void AnimationComponent::advanceThreads(F32 dt) if (!mOwnerRenderInst) return; + if (mOwnerShapeInstance == nullptr || !getShape()) + return; + for (U32 i = 0; i < MaxScriptThreads; i++) { Thread& st = mAnimationThreads[i]; @@ -647,7 +630,7 @@ void AnimationComponent::advanceThreads(F32 dt) st.atEnd = true; updateThread(st); - if (!isGhost()) + if (!isClientObject()) { Con::executef(this, "onAnimationEnd", st.thread->getSequenceName()); } @@ -660,7 +643,7 @@ void AnimationComponent::advanceThreads(F32 dt) mOwnerShapeInstance->advanceTime(dt, st.thread); } - if (mOwnerShapeInstance && !isGhost()) + if (mOwnerShapeInstance && !isClientObject()) { for (U32 i = 1; i < 32; i++) { @@ -672,8 +655,16 @@ void AnimationComponent::advanceThreads(F32 dt) } } - if (isGhost()) + if (isClientObject()) + { mOwnerShapeInstance->animate(); + /*mOwnerShapeInstance->animateGround(); + MatrixF groundTransform = mOwnerShapeInstance->getGroundTransform(); + if (groundTransform != MatrixF::Identity) + { + mOwner->setPosition(groundTransform.getPosition()); + }*/ + } } } } diff --git a/Engine/source/T3D/components/audio/SoundComponent.cpp b/Engine/source/T3D/components/audio/SoundComponent.cpp new file mode 100644 index 000000000..9552c2d67 --- /dev/null +++ b/Engine/source/T3D/components/audio/SoundComponent.cpp @@ -0,0 +1,422 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "T3D/components/audio/SoundComponent.h" +#include "core/stream/bitStream.h" +#include "sim/netConnection.h" + +#include "sfx/sfxSystem.h" +#include "sfx/sfxSource.h" +#include "sfx/sfxTrack.h" +#include "sfx/sfxDescription.h" +#include "T3D/sfx/sfx3DWorld.h" + +#include "sfx/sfxTrack.h" +#include "sfx/sfxTypes.h" + +#include "renderInstance/renderPassManager.h" +#include "gfx/gfxDrawUtil.h" + +// Timeout for non-looping sounds on a channel +static SimTime sAudioTimeout = 500; + +extern bool gEditingMission; + +////////////////////////////////////////////////////////////////////////// +// Constructor/Destructor +////////////////////////////////////////////////////////////////////////// +SoundComponent::SoundComponent() : Component() +{ + //These flags inform that, in this particular component, we network down to the client, which enables the pack/unpackData functions to operate + mNetworked = true; + + mFriendlyName = "Sound(Component)"; + mComponentType = "Sound"; + mDescription = getDescriptionText("Stores up to 4 sounds for playback."); + + for (U32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) { + mSoundThread[slotNum].play = false; + mSoundThread[slotNum].profile = 0; + mSoundThread[slotNum].sound = 0; + + mSoundFile[slotNum] = NULL; + mPreviewSound[slotNum] = false; + mPlay[slotNum] = false; + } +} + +SoundComponent::~SoundComponent() +{ +} + +IMPLEMENT_CO_NETOBJECT_V1(SoundComponent); + +//Standard onAdd function, for when the component is created +bool SoundComponent::onAdd() +{ + if (!Parent::onAdd()) + return false; + + for (U32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + mPreviewSound[slotNum] = false; + + return true; +} + +//Standard onRemove function, when the component object is deleted +void SoundComponent::onRemove() +{ + Parent::onRemove(); +} + +//This is called when the component has been added to an entity +void SoundComponent::onComponentAdd() +{ + Parent::onComponentAdd(); + + Con::printf("We were added to an entity! SoundComponent reporting in for owner entity %i", mOwner->getId()); +} + +//This is called when the component has been removed from an entity +void SoundComponent::onComponentRemove() +{ + Con::printf("We were removed from our entity! SoundComponent signing off for owner entity %i", mOwner->getId()); + Parent::onComponentRemove(); +} + +//This is called any time a component is added to an entity. Every component currently owned by the entity is informed of the event. +//This allows you to do dependency behavior, like collisions being aware of a mesh component, etc +void SoundComponent::componentAddedToOwner(Component *comp) +{ + for (S32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + { + if (mPlay[slotNum]) + { + playAudio(slotNum, mSoundFile[slotNum]); + } + } + Con::printf("Our owner entity has a new component being added! SoundComponent welcomes component %i of type %s", comp->getId(), comp->getClassRep()->getNameSpace()); +} + +//This is called any time a component is removed from an entity. Every component current owned by the entity is informed of the event. +//This allows cleanup and dependency management. +void SoundComponent::componentRemovedFromOwner(Component *comp) +{ + Con::printf("Our owner entity has a removed a component! SoundComponent waves farewell to component %i of type %s", comp->getId(), comp->getClassRep()->getNameSpace()); +} + +//Regular init persist fields function to set up static fields. +void SoundComponent::initPersistFields() +{ + //addArray("Sounds", MaxSoundThreads); + addField("mSoundFile", TypeSFXTrackName, Offset(mSoundFile, SoundComponent), MaxSoundThreads, "If the text will not fit in the control, the deniedSound is played."); + addProtectedField("mPreviewSound", TypeBool, Offset(mPreviewSound, SoundComponent), + &_previewSound, &defaultProtectedGetFn, MaxSoundThreads, "Preview Sound", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors); + addProtectedField("play", TypeBool, Offset(mPlay, SoundComponent), + &_autoplay, &defaultProtectedGetFn, MaxSoundThreads, "Whether playback of the emitter's sound should start as soon as the emitter object is added to the level.\n" + "If this is true, the emitter will immediately start to play when the level is loaded."); + //endArray("Sounds"); + Parent::initPersistFields(); +} + +bool SoundComponent::_previewSound(void *object, const char *index, const char *data) +{ + U32 slotNum = (index != NULL) ? dAtoui(index) : 0; + SoundComponent* component = reinterpret_cast< SoundComponent* >(object); + if (!component->mPreviewSound[slotNum]) + component->playAudio(slotNum, component->mSoundFile[slotNum]); + else + component->stopAudio(slotNum); + component->mPreviewSound[slotNum] = !component->mPreviewSound[slotNum]; + + return false; +} + +bool SoundComponent::_autoplay(void *object, const char *index, const char *data) +{ + U32 slotNum = (index != NULL) ? dAtoui(index) : 0; + SoundComponent* component = reinterpret_cast< SoundComponent* >(object); + component->mPlay[slotNum] = dAtoui(data); + if (component->mPlay[slotNum]) + component->playAudio(slotNum, component->mSoundFile[slotNum]); + else + component->stopAudio(slotNum); + + return false; +} + +U32 SoundComponent::packUpdate(NetConnection *con, U32 mask, BitStream *stream) +{ + U32 retMask = Parent::packUpdate(con, mask, stream); + + if (mask & InitialUpdateMask) + { + // mask off sounds that aren't playing + S32 slotNum; + for (slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + if (!mSoundThread[slotNum].play) + mask &= ~(SoundMaskN << slotNum); + } + + for (S32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + stream->writeFlag(mPreviewSound[slotNum]); + + if (stream->writeFlag(mask & SoundMask)) + { + for (S32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + { + Sound& st = mSoundThread[slotNum]; + + if (stream->writeFlag(mask & (SoundMaskN << slotNum))) + { + if (stream->writeFlag(st.play)) + //stream->writeRangedU32(st.profile->getId(), DataBlockObjectIdFirst, + // DataBlockObjectIdLast); + stream->writeString(st.profile->getName()); + + } + } + } + + return retMask; +} + +void SoundComponent::unpackUpdate(NetConnection *con, BitStream *stream) +{ + Parent::unpackUpdate(con, stream); + + for (S32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + mPreviewSound[slotNum] = stream->readFlag(); + + if (stream->readFlag()) + { + for (S32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + { + if (stream->readFlag()) + { + Sound& st = mSoundThread[slotNum]; + st.play = stream->readFlag(); + if (st.play) + { + //st.profile = (SFXTrack*)stream->readRangedU32(DataBlockObjectIdFirst, + // DataBlockObjectIdLast); + char profileName[255]; + stream->readString(profileName); + + if (!Sim::findObject(profileName, st.profile)) + Con::errorf("Could not find SFXTrack"); + } + + //if (isProperlyAdded()) + updateAudioState(st); + } + } + } +} + +//This allows custom behavior in the event the owner is being edited +void SoundComponent::onInspect() +{ +} + +//This allows cleanup of the custom editor behavior if our owner stopped being edited +void SoundComponent::onEndInspect() +{ +} + +//Process tick update function, natch +void SoundComponent::processTick() +{ + Parent::processTick(); +} + +//Client-side advance function +void SoundComponent::advanceTime(F32 dt) +{ + +} + +//Client-side interpolation function +void SoundComponent::interpolateTick(F32 delta) +{ + +} + +void SoundComponent::prepRenderImage(SceneRenderState *state) +{ + if (!mEnabled || !mOwner || !gEditingMission) + return; + ObjectRenderInst* ri = state->getRenderPass()->allocInst< ObjectRenderInst >(); + + ri->renderDelegate.bind(this, &SoundComponent::_renderObject); + ri->type = RenderPassManager::RIT_Editor; + ri->defaultKey = 0; + ri->defaultKey2 = 0; + + state->getRenderPass()->addInst(ri); +} + +void SoundComponent::_renderObject(ObjectRenderInst *ri, + SceneRenderState *state, + BaseMatInstance *overrideMat) +{ + if (overrideMat) + return; + + GFXStateBlockDesc desc; + desc.setBlend(true); + + MatrixF camera = GFX->getWorldMatrix(); + camera.inverse(); + Point3F pos = mOwner->getPosition(); + + for (S32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + { + if (mPreviewSound[slotNum]) + { + Sound& st = mSoundThread[slotNum]; + if (st.sound && st.sound->getDescription()) + { + F32 minRad = st.sound->getDescription()->mMinDistance; + F32 falloffRad = st.sound->getDescription()->mMaxDistance; + SphereF sphere(pos, falloffRad); + if (sphere.isContained(camera.getPosition())) + desc.setCullMode(GFXCullNone); + + GFX->getDrawUtil()->drawSphere(desc, minRad, pos, ColorI(255, 0, 255, 64)); + GFX->getDrawUtil()->drawSphere(desc, falloffRad, pos, ColorI(128, 0, 128, 64)); + } + } + } +} + +void SoundComponent::playAudio(U32 slotNum, SFXTrack* _profile) +{ + AssertFatal(slotNum < MaxSoundThreads, "ShapeBase::playAudio() bad slot index"); + SFXTrack* profile = (_profile != NULL) ? _profile : mSoundFile[slotNum]; + Sound& st = mSoundThread[slotNum]; + if (profile && (!st.play || st.profile != profile)) + { + setMaskBits(SoundMaskN << slotNum); + st.play = true; + st.profile = profile; + updateAudioState(st); + } +} + +void SoundComponent::stopAudio(U32 slotNum) +{ + AssertFatal(slotNum < MaxSoundThreads, "ShapeBase::stopAudio() bad slot index"); + + Sound& st = mSoundThread[slotNum]; + if (st.play) + { + st.play = false; + setMaskBits(SoundMaskN << slotNum); + updateAudioState(st); + } +} + +void SoundComponent::updateServerAudio() +{ + // Timeout non-looping sounds + for (S32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + { + Sound& st = mSoundThread[slotNum]; + if (st.play && st.timeout && st.timeout < Sim::getCurrentTime()) + { + //clearMaskBits(SoundMaskN << slotNum); + st.play = false; + } + } +} + +void SoundComponent::updateAudioState(Sound& st) +{ + SFX_DELETE(st.sound); + + if (st.play && st.profile) + { + if (isClientObject()) + { + //if (Sim::findObject(SimObjectId((uintptr_t)st.profile), st.profile)) + // { + MatrixF transform = mOwner->getTransform(); + st.sound = SFX->createSource(st.profile, &transform); + if (st.sound) + st.sound->play(); + //} + else + st.play = false; + } + else + { + // Non-looping sounds timeout on the server + st.timeout = 0; + if (!st.profile->getDescription()->mIsLooping) + st.timeout = Sim::getCurrentTime() + sAudioTimeout; + } + } + else + st.play = false; +} + +void SoundComponent::updateAudioPos() +{ + for (S32 slotNum = 0; slotNum < MaxSoundThreads; slotNum++) + { + SFXSource* source = mSoundThread[slotNum].sound; + if (source) + source->setTransform(mOwner->getTransform()); + } +} + +//---------------------------------------------------------------------------- +DefineEngineMethod(SoundComponent, playAudio, bool, (S32 slot, SFXTrack* track), (0, nullAsType()), + "@brief Attach a sound to this shape and start playing it.\n\n" + + "@param slot Audio slot index for the sound (valid range is 0 - 3)\n" // 3 = ShapeBase::MaxSoundThreads-1 + "@param track SFXTrack to play\n" + "@return true if the sound was attached successfully, false if failed\n\n" + + "@see stopAudio()\n") +{ + if (track && slot >= 0 && slot < SoundComponent::MaxSoundThreads) { + object->playAudio(slot, track); + return true; + } + return false; +} + +DefineEngineMethod(SoundComponent, stopAudio, bool, (S32 slot), , + "@brief Stop a sound started with playAudio.\n\n" + + "@param slot audio slot index (started with playAudio)\n" + "@return true if the sound was stopped successfully, false if failed\n\n" + + "@see playAudio()\n") +{ + if (slot >= 0 && slot < SoundComponent::MaxSoundThreads) { + object->stopAudio(slot); + return true; + } + return false; +} \ No newline at end of file diff --git a/Engine/source/T3D/components/audio/SoundComponent.h b/Engine/source/T3D/components/audio/SoundComponent.h new file mode 100644 index 000000000..a56bc600e --- /dev/null +++ b/Engine/source/T3D/components/audio/SoundComponent.h @@ -0,0 +1,129 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef EXAMPLE_COMPONENT_H +#define EXAMPLE_COMPONENT_H +#pragma once + +#ifndef COMPONENT_H +#include "T3D/components/component.h" +#endif +#ifndef RENDER_COMPONENT_INTERFACE_H +#include "T3D/components/render/renderComponentInterface.h" +#endif + +class SFXSource; + +//SoundComponent +//A basic example of the various functions you can utilize to make your own component! +//This example doesn't really DO anything, persay, but you can readily copy it as a base +//and use it as a starting point for your own. +class SoundComponent : public Component, public RenderComponentInterface, public EditorInspectInterface +{ + typedef Component Parent; + +public: + enum PublicConstants + { + MaxSoundThreads = 4, ///< Should be a power of 2 + }; + + /// @name Network state masks + /// @{ + + /// + enum SoundComponentMasks + { + SoundMaskN = Parent::NextFreeMask << 6, ///< Extends + MaxSoundThreads bits + }; + + enum BaseMaskConstants + { + SoundMask = (SoundMaskN << MaxSoundThreads) - SoundMaskN, + }; + /// @name Scripted Sound + /// @{ + struct Sound { + bool play; ///< Are we playing this sound? + SimTime timeout; ///< Time until we stop playing this sound. + SFXTrack* profile; ///< Profile on server + SFXSource* sound; ///< Sound on client + Sound() + { + play = false; + timeout = 0; + profile = NULL; + sound = NULL; + } + }; + Sound mSoundThread[MaxSoundThreads]; + SFXTrack* mSoundFile[MaxSoundThreads]; + bool mPreviewSound[MaxSoundThreads]; + bool mPlay[MaxSoundThreads]; + /// @} + + SoundComponent(); + virtual ~SoundComponent(); + DECLARE_CONOBJECT(SoundComponent); + + virtual bool onAdd(); + virtual void onRemove(); + static void initPersistFields(); + static bool _previewSound(void *object, const char *index, const char *data); + static bool _autoplay(void *object, const char *index, const char *data); + + virtual U32 packUpdate(NetConnection *con, U32 mask, BitStream *stream); + virtual void unpackUpdate(NetConnection *con, BitStream *stream); + + virtual void onComponentRemove(); + virtual void onComponentAdd(); + + virtual void componentAddedToOwner(Component *comp); + virtual void componentRemovedFromOwner(Component *comp); + + virtual void onInspect(); + virtual void onEndInspect(); + + virtual void processTick(); + virtual void advanceTime(F32 dt); + virtual void interpolateTick(F32 delta); + + void prepRenderImage(SceneRenderState* state); + void _renderObject(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat); + + virtual void playAudio(U32 slotNum, SFXTrack* profile = NULL); + virtual void stopAudio(U32 slot); + virtual void updateServerAudio(); + virtual void updateAudioState(Sound& st); + virtual void updateAudioPos(); + + //why god why + virtual TSShape* getShape() { return NULL; }; + Signal< void(RenderComponentInterface*) > onShapeChanged; + virtual TSShapeInstance* getShapeInstance() { return NULL; }; + Signal< void(RenderComponentInterface*) > onShapeInstanceChanged; + virtual MatrixF getNodeTransform(S32 nodeIdx) { return MatrixF::Identity; }; + virtual Vector getNodeTransforms() { return NULL; }; + virtual void setNodeTransforms(Vector transforms) {}; +}; + +#endif \ No newline at end of file diff --git a/Engine/source/T3D/components/camera/cameraComponent.cpp b/Engine/source/T3D/components/camera/cameraComponent.cpp index 60c62fb3a..2cd1b7d08 100644 --- a/Engine/source/T3D/components/camera/cameraComponent.cpp +++ b/Engine/source/T3D/components/camera/cameraComponent.cpp @@ -79,6 +79,7 @@ CameraComponent::CameraComponent() : Component() mTargetNode = ""; mUseParentTransform = true; + mNetworked = true; mFriendlyName = "Camera(Component)"; } @@ -202,7 +203,7 @@ void CameraComponent::setCameraFov(F32 fov) void CameraComponent::onCameraScopeQuery(NetConnection *cr, CameraScopeQuery * query) { // update the camera query - query->camera = this; + query->camera = mOwner;//this; if(GameConnection * con = dynamic_cast(cr)) { @@ -357,7 +358,8 @@ U32 CameraComponent::packUpdate(NetConnection *con, U32 mask, BitStream *stream) mTargetNodeIdx = nodeIndex; } - stream->writeInt(mTargetNodeIdx, 32); + if(stream->writeFlag(mTargetNodeIdx > -1)) + stream->writeInt(mTargetNodeIdx, 32); //send offsets here stream->writeCompressedPoint(mPosOffset); @@ -382,7 +384,10 @@ void CameraComponent::unpackUpdate(NetConnection *con, BitStream *stream) if(stream->readFlag()) { - mTargetNodeIdx = stream->readInt(32); + if (stream->readFlag()) + mTargetNodeIdx = stream->readInt(32); + else + mTargetNodeIdx = -1; stream->readCompressedPoint(&mPosOffset); diff --git a/Engine/source/T3D/components/collision/collisionComponent.cpp b/Engine/source/T3D/components/collision/collisionComponent.cpp index e680665dc..3736fbe04 100644 --- a/Engine/source/T3D/components/collision/collisionComponent.cpp +++ b/Engine/source/T3D/components/collision/collisionComponent.cpp @@ -125,8 +125,6 @@ EndImplementEnumType; // CollisionComponent::CollisionComponent() : Component() { - mNetFlags.set(Ghostable | ScopeAlways); - mFriendlyName = "Collision(Component)"; mOwnerRenderInterface = NULL; @@ -144,10 +142,12 @@ CollisionComponent::CollisionComponent() : Component() StaticShapeObjectType | VehicleObjectType | VehicleBlockerObjectType | DynamicShapeObjectType | StaticObjectType | EntityObjectType | TriggerObjectType); - mPhysicsRep = NULL; - mPhysicsWorld = NULL; + mPhysicsRep = nullptr; + mPhysicsWorld = nullptr; - mTimeoutList = NULL; + mTimeoutList = nullptr; + + mAnimated = false; } CollisionComponent::~CollisionComponent() diff --git a/Engine/source/T3D/components/component.cpp b/Engine/source/T3D/components/component.cpp index cbb2305c1..181c892e5 100644 --- a/Engine/source/T3D/components/component.cpp +++ b/Engine/source/T3D/components/component.cpp @@ -31,6 +31,7 @@ #include "console/engineAPI.h" #include "sim/netConnection.h" #include "console/consoleInternal.h" +#include "T3D/assets/MaterialAsset.h" #define DECLARE_NATIVE_COMPONENT( ComponentType ) \ Component* staticComponentTemplate = new ComponentType; \ @@ -52,7 +53,6 @@ Component::Component() mNetworked = false; - // [tom, 1/12/2007] We manage the memory for the description since it // could be loaded from a file and thus massive. This is accomplished with // protected fields, but since they still call Con::getData() the field @@ -66,7 +66,14 @@ Component::Component() mOriginatingAssetId = StringTable->EmptyString(); - mNetFlags.set(Ghostable); + mIsServerObject = true; + + componentIdx = 0; + + mHidden = false; + mEnabled = true; + + mDirtyMaskBits = 0; } Component::~Component() @@ -198,7 +205,6 @@ void Component::onComponentRemove() { mOwner->onComponentAdded.remove(this, &Component::componentAddedToOwner); mOwner->onComponentRemoved.remove(this, &Component::componentRemovedFromOwner); - mOwner->onTransformSet.remove(this, &Component::ownerTransformSet); } mOwner = NULL; @@ -212,7 +218,6 @@ void Component::setOwner(Entity* owner) { mOwner->onComponentAdded.remove(this, &Component::componentAddedToOwner); mOwner->onComponentRemoved.remove(this, &Component::componentRemovedFromOwner); - mOwner->onTransformSet.remove(this, &Component::ownerTransformSet); mOwner->removeComponent(this, false); } @@ -223,11 +228,18 @@ void Component::setOwner(Entity* owner) { mOwner->onComponentAdded.notify(this, &Component::componentAddedToOwner); mOwner->onComponentRemoved.notify(this, &Component::componentRemovedFromOwner); - mOwner->onTransformSet.notify(this, &Component::ownerTransformSet); } if (isServerObject()) + { setMaskBits(OwnerMask); + + //if we have any outstanding maskbits, push them along to have the network update happen on the entity + if (mDirtyMaskBits != 0 && mOwner) + { + mOwner->setMaskBits(Entity::ComponentsUpdateMask); + } + } } void Component::componentAddedToOwner(Component *comp) @@ -240,16 +252,19 @@ void Component::componentRemovedFromOwner(Component *comp) return; } -void Component::ownerTransformSet(MatrixF *mat) +void Component::setMaskBits(U32 orMask) { - return; + AssertFatal(orMask != 0, "Invalid net mask bits set."); + + if (mOwner) + mOwner->setComponentNetMask(this, orMask); } U32 Component::packUpdate(NetConnection *con, U32 mask, BitStream *stream) { - U32 retMask = Parent::packUpdate(con, mask, stream); + U32 retMask = 0; - if (mask & OwnerMask) + /*if (mask & OwnerMask) { if (mOwner != NULL) { @@ -274,7 +289,7 @@ U32 Component::packUpdate(NetConnection *con, U32 mask, BitStream *stream) } } else - stream->writeFlag(false); + stream->writeFlag(false);*/ if (stream->writeFlag(mask & EnableMask)) { @@ -299,9 +314,7 @@ U32 Component::packUpdate(NetConnection *con, U32 mask, BitStream *stream) void Component::unpackUpdate(NetConnection *con, BitStream *stream) { - Parent::unpackUpdate(con, stream); - - if (stream->readFlag()) + /*if (stream->readFlag()) { if (stream->readFlag()) { @@ -317,7 +330,7 @@ void Component::unpackUpdate(NetConnection *con, BitStream *stream) //it's being nulled out setOwner(NULL); } - } + }*/ if (stream->readFlag()) { @@ -467,7 +480,7 @@ void Component::addComponentField(const char *fieldName, const char *desc, const else if (fieldType == StringTable->insert("vector")) fieldTypeMask = TypePoint3F; else if (fieldType == StringTable->insert("material")) - fieldTypeMask = TypeMaterialName; + fieldTypeMask = TypeMaterialAssetPtr; else if (fieldType == StringTable->insert("image")) fieldTypeMask = TypeImageFilename; else if (fieldType == StringTable->insert("shape")) @@ -488,6 +501,7 @@ void Component::addComponentField(const char *fieldName, const char *desc, const fieldTypeMask = TypeGameObjectAssetPtr; else fieldTypeMask = TypeString; + field.mFieldTypeName = fieldType; field.mFieldType = fieldTypeMask; @@ -528,7 +542,7 @@ const char * Component::getDescriptionText(const char *desc) if (desc == NULL) return NULL; - char *newDesc; + char *newDesc = ""; // [tom, 1/12/2007] If it isn't a file, just do it the easy way if (!Platform::isFile(desc)) @@ -561,7 +575,7 @@ const char * Component::getDescriptionText(const char *desc) } str.close(); - delete stream; + //delete stream; return newDesc; } diff --git a/Engine/source/T3D/components/component.h b/Engine/source/T3D/components/component.h index 4f84de17f..b585a30b0 100644 --- a/Engine/source/T3D/components/component.h +++ b/Engine/source/T3D/components/component.h @@ -64,9 +64,9 @@ struct ComponentField /// /// ////////////////////////////////////////////////////////////////////////// -class Component : public NetObject, public UpdateInterface +class Component : public SimObject, public UpdateInterface { - typedef NetObject Parent; + typedef SimObject Parent; protected: StringTableEntry mFriendlyName; @@ -92,6 +92,10 @@ protected: StringTableEntry mOriginatingAssetId; AssetPtr mOriginatingAsset; + U32 mDirtyMaskBits; + + bool mIsServerObject; + public: Component(); virtual ~Component(); @@ -113,7 +117,8 @@ public: //This is called when a different component is removed from our owner entity virtual void componentRemovedFromOwner(Component *comp); - virtual void ownerTransformSet(MatrixF *mat); + //Overridden by components that actually care + virtual void ownerTransformSet(MatrixF *mat) {} void setOwner(Entity* pOwner); inline Entity *getOwner() { return mOwner ? mOwner : NULL; } @@ -190,6 +195,16 @@ public: NextFreeMask = BIT(5) }; + virtual void setMaskBits(U32 orMask); + virtual void clearMaskBits() { + mDirtyMaskBits = 0; + } + + bool isServerObject() { return mIsServerObject; } + bool isClientObject() { return !mIsServerObject; } + + void setIsServerObject(bool isServerObj) { mIsServerObject = isServerObj; } + virtual U32 packUpdate(NetConnection *con, U32 mask, BitStream *stream); virtual void unpackUpdate(NetConnection *con, BitStream *stream); /// @} diff --git a/Engine/source/T3D/components/game/stateMachine.cpp b/Engine/source/T3D/components/game/stateMachine.cpp index 335b69db3..fd1ef8505 100644 --- a/Engine/source/T3D/components/game/stateMachine.cpp +++ b/Engine/source/T3D/components/game/stateMachine.cpp @@ -30,6 +30,10 @@ StateMachine::StateMachine() mStartingState = ""; mCurCreateState = NULL; + + mStateMachineFile = StringTable->EmptyString(); + + mCurCreateState = nullptr; } StateMachine::~StateMachine() diff --git a/Engine/source/T3D/components/game/stateMachine.h b/Engine/source/T3D/components/game/stateMachine.h index 9ccc540e8..b440ab7fa 100644 --- a/Engine/source/T3D/components/game/stateMachine.h +++ b/Engine/source/T3D/components/game/stateMachine.h @@ -158,6 +158,8 @@ public: { if (index <= mFields.size()) return mFields[index]; + + return StateField(); //return a blank one } Signal< void(StateMachine*, S32 stateIdx) > onStateChanged; diff --git a/Engine/source/T3D/components/game/stateMachineComponent.cpp b/Engine/source/T3D/components/game/stateMachineComponent.cpp index 991d41ce1..d4e9a7d73 100644 --- a/Engine/source/T3D/components/game/stateMachineComponent.cpp +++ b/Engine/source/T3D/components/game/stateMachineComponent.cpp @@ -57,7 +57,6 @@ StateMachineComponent::StateMachineComponent() : Component() //doesn't need to be networked mNetworked = false; - mNetFlags.clear(); } StateMachineComponent::~StateMachineComponent() diff --git a/Engine/source/T3D/components/physics/playerControllerComponent.cpp b/Engine/source/T3D/components/physics/playerControllerComponent.cpp index 2c6cea6e9..761ac570c 100644 --- a/Engine/source/T3D/components/physics/playerControllerComponent.cpp +++ b/Engine/source/T3D/components/physics/playerControllerComponent.cpp @@ -119,8 +119,11 @@ PlayerControllerComponent::PlayerControllerComponent() : Component() mInputVelocity = Point3F(0, 0, 0); - mPhysicsRep = NULL; - mPhysicsWorld = NULL; + mPhysicsRep = nullptr; + mPhysicsWorld = nullptr; + + mOwnerCollisionInterface = nullptr; + mIntegrationCount = 0; } PlayerControllerComponent::~PlayerControllerComponent() diff --git a/Engine/source/T3D/components/physics/rigidBodyComponent.cpp b/Engine/source/T3D/components/physics/rigidBodyComponent.cpp index 21e9ecdbe..200e0d65e 100644 --- a/Engine/source/T3D/components/physics/rigidBodyComponent.cpp +++ b/Engine/source/T3D/components/physics/rigidBodyComponent.cpp @@ -288,7 +288,7 @@ void RigidBodyComponent::processTick() return; // SINGLE PLAYER HACK!!!! - if (PHYSICSMGR->isSinglePlayer() && isClientObject() && getServerObject()) + /*if (PHYSICSMGR->isSinglePlayer() && isClientObject() && getServerObject()) { RigidBodyComponent *servObj = (RigidBodyComponent*)getServerObject(); mOwner->setTransform(servObj->mState.getTransform()); @@ -296,7 +296,7 @@ void RigidBodyComponent::processTick() mRenderState[1] = servObj->mRenderState[1]; return; - } + }*/ // Store the last render state. mRenderState[0] = mRenderState[1]; diff --git a/Engine/source/T3D/components/render/meshComponent.cpp b/Engine/source/T3D/components/render/meshComponent.cpp index c9eeee3c3..c87733bf8 100644 --- a/Engine/source/T3D/components/render/meshComponent.cpp +++ b/Engine/source/T3D/components/render/meshComponent.cpp @@ -45,52 +45,49 @@ #include "core/strings/findMatch.h" #include "T3D/components/render/meshComponent_ScriptBinding.h" +ImplementEnumType(BatchingMode, + "Type of mesh data available in a shape.\n" + "@ingroup gameObjects") +{ + MeshComponent::Individual, "Individual", "This mesh is rendered indivudally, wthout batching or instancing." +}, + { MeshComponent::StaticBatch, "Static Batching", "Statically batches this mesh together with others to reduce drawcalls." }, + //{ MeshComponent::DynamicBatch, "Dynamic Batching", "Dynamical batches this mesh together with others to reduce drawcalls each frame." }, + // { MeshComponent::Instanced, "Instanced", "This mesh is rendered as an instance, reducing draw overhead with others that share the same mesh and material." }, + EndImplementEnumType; + ////////////////////////////////////////////////////////////////////////// // Constructor/Destructor ////////////////////////////////////////////////////////////////////////// -MeshComponent::MeshComponent() : Component() +MeshComponent::MeshComponent() : Component(), mShape(nullptr), mRenderMode(Individual) { - mShapeName = StringTable->insert(""); - mShapeAsset = StringTable->insert(""); - mShapeInstance = NULL; - - mChangingMaterials.clear(); - - mMaterials.clear(); - mFriendlyName = "Mesh Component"; mComponentType = "Render"; mDescription = getDescriptionText("Causes the object to render a non-animating 3d shape using the file provided."); mNetworked = true; - mNetFlags.set(Ghostable | ScopeAlways); + + mShapeName = StringTable->EmptyString(); + mShapeAsset = StringTable->EmptyString(); + + mMeshAsset = StringTable->EmptyString(); + mMeshAssetId = StringTable->EmptyString(); + + mInterfaceData = new MeshRenderSystemInterface(); + + mRenderMode = Individual; } -MeshComponent::~MeshComponent(){} +MeshComponent::~MeshComponent() +{ + if (mInterfaceData) + SAFE_DELETE(mInterfaceData); +} IMPLEMENT_CO_NETOBJECT_V1(MeshComponent); //========================================================================================== -void MeshComponent::boneObject::addObject(SimObject* object) -{ - SceneObject* sc = dynamic_cast(object); - - if(sc && mOwner) - { - if(TSShape* shape = mOwner->getShape()) - { - S32 nodeID = shape->findNode(mBoneName); - - //we may have a offset on the shape's center - //so make sure we accomodate for that when setting up the mount offsets - MatrixF mat = mOwner->getNodeTransform(nodeID); - - mOwner->getOwner()->mountObject(sc, nodeID, mat); - } - } -} - bool MeshComponent::onAdd() { if(! Parent::onAdd()) @@ -106,6 +103,12 @@ void MeshComponent::onComponentAdd() { Parent::onComponentAdd(); + if (isClientObject()) + mInterfaceData->mIsClient = true; + + // if (mInterfaceData != nullptr) + // mInterfaceData->mIsClient = isClientObject(); + //get the default shape, if any updateShape(); } @@ -113,10 +116,6 @@ void MeshComponent::onComponentAdd() void MeshComponent::onRemove() { Parent::onRemove(); - - mMeshAsset.clear(); - - SAFE_DELETE(mShapeInstance); } void MeshComponent::onComponentRemove() @@ -135,9 +134,14 @@ void MeshComponent::initPersistFields() { Parent::initPersistFields(); + addGroup("Rendering"); + addField("BatchingMode", TypeBatchingMode, Offset(mRenderMode, MeshComponent), + "The mode of batching this shape should be rendered with."); + endGroup("Rendering"); + //create a hook to our internal variables addGroup("Model"); - addProtectedField("MeshAsset", TypeAssetId, Offset(mShapeAsset, MeshComponent), &_setMesh, &defaultProtectedGetFn, + addProtectedField("MeshAsset", TypeShapeAssetPtr, Offset(mShapeAsset, MeshComponent), &_setMesh, &defaultProtectedGetFn, "The asset Id used for the mesh.", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors); endGroup("Model"); } @@ -165,6 +169,9 @@ bool MeshComponent::_setShape( void *object, const char *index, const char *data bool MeshComponent::setMeshAsset(const char* assetName) { // Fetch the asset Id. + if (mInterfaceData == nullptr) + return false; + mMeshAssetId = StringTable->insert(assetName); mMeshAsset = mMeshAssetId; @@ -183,9 +190,129 @@ bool MeshComponent::setMeshAsset(const char* assetName) return true; } +void MeshComponent::updateShape() +{ + if (mInterfaceData == nullptr) + return; + + //if ((mShapeName && mShapeName[0] != '\0') || (mShapeAsset && mShapeAsset[0] != '\0')) + if ((mShapeName && mShapeName[0] != '\0') || (mMeshAssetId && mMeshAssetId[0] != '\0')) + + { + if (mMeshAsset == NULL) + return; + + mShape = mMeshAsset->getShape(); + + if (!mMeshAsset->getShape()) + return; + + setupShape(); + + //Do this on both the server and client + S32 materialCount = mMeshAsset->getShape()->materialList->getMaterialNameList().size(); + + if (isServerObject()) + { + //we need to update the editor + for (U32 i = 0; i < mFields.size(); i++) + { + //find any with the materialslot title and clear them out + if (FindMatch::isMatch("MaterialSlot*", mFields[i].mFieldName, false)) + { + setDataField(mFields[i].mFieldName, NULL, ""); + mFields.erase(i); + continue; + } + } + + //next, get a listing of our materials in the shape, and build our field list for them + char matFieldName[128]; + + if (materialCount > 0) + mComponentGroup = StringTable->insert("Materials"); + + for (U32 i = 0; i < materialCount; i++) + { + String materialname = mMeshAsset->getShape()->materialList->getMaterialName(i); + if (materialname == String("ShapeBounds")) + continue; + + dSprintf(matFieldName, 128, "MaterialSlot%d", i); + + addComponentField(matFieldName, "A material used in the shape file", "Material", materialname, ""); + } + + if (materialCount > 0) + mComponentGroup = ""; + } + + if (mOwner != NULL) + { + Point3F min, max, pos; + pos = mOwner->getPosition(); + + mOwner->getWorldToObj().mulP(pos); + + min = mMeshAsset->getShape()->bounds.minExtents; + max = mMeshAsset->getShape()->bounds.maxExtents; + + if (mInterfaceData) + { + mInterfaceData->mBounds.set(min, max); + mInterfaceData->mScale = mOwner->getScale(); + mInterfaceData->mTransform = mOwner->getRenderTransform(); + } + + mOwner->setObjectBox(Box3F(min, max)); + + mOwner->resetWorldBox(); + + if (mOwner->getSceneManager() != NULL) + mOwner->getSceneManager()->notifyObjectDirty(mOwner); + } + + if (isClientObject() && mInterfaceData) + { + if (mRenderMode == StaticBatch) + { + mInterfaceData->mStatic = true; + + OptimizedPolyList geom; + MatrixF transform = mInterfaceData->mTransform; + mInterfaceData->mGeometry.setTransform(&transform, mInterfaceData->mScale); + mInterfaceData->mGeometry.setObject(mOwner); + + mInterfaceData->mShapeInstance->buildPolyList(&mInterfaceData->mGeometry, 0); + } + else + { + mInterfaceData->mStatic = false; + } + + MeshRenderSystem::rebuildBuffers(); + } + + //finally, notify that our shape was changed + onShapeInstanceChanged.trigger(this); + } +} + +void MeshComponent::setupShape() +{ + mInterfaceData->mShapeInstance = new TSShapeInstance(mMeshAsset->getShape(), true); +} + void MeshComponent::_onResourceChanged( const Torque::Path &path ) { - if ( path != Torque::Path( mShapeName ) ) + if (mInterfaceData == nullptr) + return; + + String filePath; + if (mMeshAsset) + filePath = Torque::Path(mMeshAsset->getShapeFilename()); + + if (!mMeshAsset || path != Torque::Path(mMeshAsset->getShapeFilename()) ) return; updateShape(); @@ -216,6 +343,8 @@ U32 MeshComponent::packUpdate(NetConnection *con, U32 mask, BitStream *stream) if (stream->writeFlag(mask & ShapeMask)) { stream->writeString(mShapeName); + + stream->writeInt(mRenderMode, 8); } if (stream->writeFlag( mask & MaterialMask )) @@ -226,7 +355,7 @@ U32 MeshComponent::packUpdate(NetConnection *con, U32 mask, BitStream *stream) { stream->writeInt(mChangingMaterials[i].slot, 16); - NetStringHandle matNameStr = mChangingMaterials[i].matName.c_str(); + NetStringHandle matNameStr = mChangingMaterials[i].assetId.c_str(); con->packNetStringHandleU(stream, matNameStr); } @@ -243,6 +372,8 @@ void MeshComponent::unpackUpdate(NetConnection *con, BitStream *stream) if(stream->readFlag()) { mShapeName = stream->readSTString(); + + mRenderMode = (RenderMode)stream->readInt(8); setMeshAsset(mShapeName); updateShape(); } @@ -256,7 +387,10 @@ void MeshComponent::unpackUpdate(NetConnection *con, BitStream *stream) { matMap newMatMap; newMatMap.slot = stream->readInt(16); - newMatMap.matName = String(con->unpackNetStringHandleU(stream).getString()); + newMatMap.assetId = String(con->unpackNetStringHandleU(stream).getString()); + + //do the lookup, now + newMatMap.matAsset = AssetDatabase.acquireAsset(newMatMap.assetId); mChangingMaterials.push_back(newMatMap); } @@ -267,7 +401,7 @@ void MeshComponent::unpackUpdate(NetConnection *con, BitStream *stream) void MeshComponent::prepRenderImage( SceneRenderState *state ) { - if (!mEnabled || !mOwner || !mShapeInstance) + /*if (!mEnabled || !mOwner || !mShapeInstance) return; Point3F cameraOffset; @@ -300,114 +434,41 @@ void MeshComponent::prepRenderImage( SceneRenderState *state ) rdata.setLightQuery(&query); MatrixF mat = mOwner->getRenderTransform(); - Point3F renderPos = mat.getPosition(); - EulerF renderRot = mat.toEuler(); + + if (mOwner->isMounted()) + { + MatrixF wrldPos = mOwner->getWorldTransform(); + Point3F wrldPosPos = wrldPos.getPosition(); + + Point3F mntPs = mat.getPosition(); + EulerF mntRt = RotationF(mat).asEulerF(); + + bool tr = true; + } + mat.scale(objScale); GFX->setWorldMatrix(mat); - mShapeInstance->render(rdata); -} - -void MeshComponent::updateShape() -{ - bool isServer = isServerObject(); - - if ((mShapeName && mShapeName[0] != '\0') || (mShapeAsset && mShapeAsset[0] != '\0')) - { - if (mMeshAsset == NULL) - return; - - mShape = mMeshAsset->getShape(); - - if (!mShape) - return; - - setupShape(); - - //Do this on both the server and client - S32 materialCount = mShape->materialList->getMaterialNameList().size(); - - if(isServerObject()) - { - //we need to update the editor - for (U32 i = 0; i < mFields.size(); i++) - { - //find any with the materialslot title and clear them out - if (FindMatch::isMatch("MaterialSlot*", mFields[i].mFieldName, false)) - { - setDataField(mFields[i].mFieldName, NULL, ""); - mFields.erase(i); - continue; - } - } - - //next, get a listing of our materials in the shape, and build our field list for them - char matFieldName[128]; - - if(materialCount > 0) - mComponentGroup = StringTable->insert("Materials"); - - for(U32 i=0; i < materialCount; i++) - { - String materialname = mShape->materialList->getMaterialName(i); - if(materialname == String("ShapeBounds")) - continue; - - dSprintf(matFieldName, 128, "MaterialSlot%d", i); - - addComponentField(matFieldName, "A material used in the shape file", "TypeAssetId", materialname, ""); - } - - if(materialCount > 0) - mComponentGroup = ""; - } - - if(mOwner != NULL) - { - Point3F min, max, pos; - pos = mOwner->getPosition(); - - mOwner->getWorldToObj().mulP(pos); - - min = mShape->bounds.minExtents; - max = mShape->bounds.maxExtents; - - mShapeBounds.set(min, max); - - mOwner->setObjectBox(Box3F(min, max)); - - if( mOwner->getSceneManager() != NULL ) - mOwner->getSceneManager()->notifyObjectDirty( mOwner ); - } - - //finally, notify that our shape was changed - onShapeInstanceChanged.trigger(this); - } -} - -void MeshComponent::setupShape() -{ - mShapeInstance = new TSShapeInstance(mShape, true); + mShapeInstance->render(rdata);*/ } void MeshComponent::updateMaterials() { - if (mChangingMaterials.empty() || !mShape) + if (mChangingMaterials.empty() || !mMeshAsset->getShape()) return; - TSMaterialList* pMatList = mShapeInstance->getMaterialList(); + TSMaterialList* pMatList = mInterfaceData->mShapeInstance->getMaterialList(); pMatList->setTextureLookupPath(getShapeResource().getPath().getPath()); const Vector &materialNames = pMatList->getMaterialNameList(); for ( S32 i = 0; i < materialNames.size(); i++ ) { - const String &pName = materialNames[i]; - for(U32 m=0; m < mChangingMaterials.size(); m++) { if(mChangingMaterials[m].slot == i) { - pMatList->renameMaterial( i, mChangingMaterials[m].matName ); + //Fetch the actual material asset + pMatList->renameMaterial( i, mChangingMaterials[m].matAsset->getMaterialDefinitionName()); } } @@ -415,22 +476,31 @@ void MeshComponent::updateMaterials() } // Initialize the material instances - mShapeInstance->initMaterialList(); + mInterfaceData->mShapeInstance->initMaterialList(); } MatrixF MeshComponent::getNodeTransform(S32 nodeIdx) { - if (mShape) + if (mInterfaceData != nullptr && mMeshAsset->getShape()) { S32 nodeCount = getShape()->nodes.size(); if(nodeIdx >= 0 && nodeIdx < nodeCount) { //animate(); - MatrixF mountTransform = mShapeInstance->mNodeTransforms[nodeIdx]; - mountTransform.mul(mOwner->getRenderTransform()); + MatrixF nodeTransform = mInterfaceData->mShapeInstance->mNodeTransforms[nodeIdx]; + const Point3F& scale = mOwner->getScale(); - return mountTransform; + // The position of the node needs to be scaled. + Point3F position = nodeTransform.getPosition(); + position.convolve(scale); + nodeTransform.setPosition(position); + + MatrixF finalTransform = MatrixF::Identity; + + finalTransform.mul(mOwner->getRenderTransform(), nodeTransform); + + return finalTransform; } } @@ -439,7 +509,7 @@ MatrixF MeshComponent::getNodeTransform(S32 nodeIdx) S32 MeshComponent::getNodeByName(String nodeName) { - if (mShape) + if (mMeshAsset->getShape()) { S32 nodeIdx = getShape()->findNode(nodeName); @@ -485,12 +555,18 @@ void MeshComponent::onDynamicModified(const char* slotName, const char* newValue if(slot == -1) return; + //Safe to assume the inbound value for the material will be a MaterialAsset, so lets do a lookup on the name + MaterialAsset* matAsset = AssetDatabase.acquireAsset(newValue); + if (!matAsset) + return; + bool found = false; for(U32 i=0; i < mChangingMaterials.size(); i++) { if(mChangingMaterials[i].slot == slot) { - mChangingMaterials[i].matName = String(newValue); + mChangingMaterials[i].matAsset = matAsset; + mChangingMaterials[i].assetId = newValue; found = true; } } @@ -499,7 +575,8 @@ void MeshComponent::onDynamicModified(const char* slotName, const char* newValue { matMap newMatMap; newMatMap.slot = slot; - newMatMap.matName = String(newValue); + newMatMap.matAsset = matAsset; + newMatMap.assetId = newValue; mChangingMaterials.push_back(newMatMap); } @@ -510,14 +587,31 @@ void MeshComponent::onDynamicModified(const char* slotName, const char* newValue Parent::onDynamicModified(slotName, newValue); } -void MeshComponent::changeMaterial(U32 slot, const char* newMat) +void MeshComponent::changeMaterial(U32 slot, MaterialAsset* newMat) { char fieldName[512]; //update our respective field dSprintf(fieldName, 512, "materialSlot%d", slot); - setDataField(fieldName, NULL, newMat); + setDataField(fieldName, NULL, newMat->getAssetId()); +} + +bool MeshComponent::setMatInstField(U32 slot, const char* field, const char* value) +{ + TSMaterialList* pMatList = mInterfaceData->mShapeInstance->getMaterialList(); + pMatList->setTextureLookupPath(getShapeResource().getPath().getPath()); + + MaterialParameters* params = pMatList->getMaterialInst(slot)->getMaterialParameters(); + + if (pMatList->getMaterialInst(slot)->getFeatures().hasFeature(MFT_DiffuseColor)) + { + MaterialParameterHandle* handle = pMatList->getMaterialInst(slot)->getMaterialParameterHandle("DiffuseColor"); + + params->set(handle, LinearColorF(0, 0, 0)); + } + + return true; } void MeshComponent::onInspect() @@ -526,4 +620,13 @@ void MeshComponent::onInspect() void MeshComponent::onEndInspect() { +} + +void MeshComponent::ownerTransformSet(MatrixF *mat) +{ + if (mInterfaceData != nullptr) + { + MatrixF newTransform = *mat; + mInterfaceData->mTransform = newTransform; + } } \ No newline at end of file diff --git a/Engine/source/T3D/components/render/meshComponent.h b/Engine/source/T3D/components/render/meshComponent.h index 6adc2633e..587038d63 100644 --- a/Engine/source/T3D/components/render/meshComponent.h +++ b/Engine/source/T3D/components/render/meshComponent.h @@ -60,6 +60,8 @@ #include "gfx/gfxVertexFormat.h" #endif +#include "T3D/systems/render/meshRenderSystem.h" + class TSShapeInstance; class SceneRenderState; ////////////////////////////////////////////////////////////////////////// @@ -84,37 +86,38 @@ protected: StringTableEntry mShapeName; StringTableEntry mShapeAsset; TSShape* mShape; - Box3F mShapeBounds; + //Box3F mShapeBounds; Point3F mCenterOffset; + MeshRenderSystemInterface* mInterfaceData; + struct matMap { - String matName; + MaterialAsset* matAsset; + String assetId; U32 slot; }; Vector mChangingMaterials; Vector mMaterials; - class boneObject : public SimGroup +public: + enum RenderMode { - MeshComponent *mOwner; - public: - boneObject(MeshComponent *owner){ mOwner = owner; } - - StringTableEntry mBoneName; - S32 mItemID; - - virtual void addObject(SimObject *obj); + Individual = 0, + DynamicBatch, + StaticBatch, + Instanced }; - Vector mNodesList; +protected: + RenderMode mRenderMode; public: StringTableEntry mMeshAssetId; AssetPtr mMeshAsset; - TSShapeInstance* mShapeInstance; + //TSShapeInstance* mShapeInstance; public: MeshComponent(); @@ -132,7 +135,7 @@ public: virtual U32 packUpdate(NetConnection *con, U32 mask, BitStream *stream); virtual void unpackUpdate(NetConnection *con, BitStream *stream); - Box3F getShapeBounds() { return mShapeBounds; } + Box3F getShapeBounds() { return mInterfaceData->mBounds; } virtual MatrixF getNodeTransform(S32 nodeIdx); S32 getNodeByName(String nodeName); @@ -144,6 +147,8 @@ public: virtual void onComponentRemove(); virtual void onComponentAdd(); + virtual void ownerTransformSet(MatrixF *mat); + static bool _setMesh(void *object, const char *index, const char *data); static bool _setShape(void *object, const char *index, const char *data); const char* _getShape(void *object, const char *data); @@ -151,7 +156,7 @@ public: bool setMeshAsset(const char* assetName); virtual TSShape* getShape() { if (mMeshAsset) return mMeshAsset->getShape(); else return NULL; } - virtual TSShapeInstance* getShapeInstance() { return mShapeInstance; } + virtual TSShapeInstance* getShapeInstance() { return mInterfaceData->mShapeInstance; } Resource getShapeResource() { return mMeshAsset->getShapeResource(); } @@ -163,7 +168,8 @@ public: virtual void onDynamicModified(const char* slotName, const char* newValue); - void changeMaterial(U32 slot, const char* newMat); + void changeMaterial(U32 slot, MaterialAsset* newMat); + bool setMatInstField(U32 slot, const char* field, const char* value); virtual void onInspect(); virtual void onEndInspect(); @@ -180,4 +186,7 @@ public: } }; +typedef MeshComponent::RenderMode BatchingMode; +DefineEnumType(BatchingMode); + #endif diff --git a/Engine/source/T3D/components/render/meshComponent_ScriptBinding.h b/Engine/source/T3D/components/render/meshComponent_ScriptBinding.h index 5a19b8f08..396166def 100644 --- a/Engine/source/T3D/components/render/meshComponent_ScriptBinding.h +++ b/Engine/source/T3D/components/render/meshComponent_ScriptBinding.h @@ -126,6 +126,28 @@ DefineEngineMethod(MeshComponent, getNodePosition, Point3F, return Point3F(0, 0, 0); } +DefineEngineMethod(MeshComponent, getNodeRotation, EulerF, + (S32 node), (-1), + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + if (node != -1) + { + //BUG: Unsure how it broke, but atm the default transform passed in here is rotated 180 degrees. This doesn't happen + //for the SceneObject mountobject method. Hackish, but for now, just default to a clean MatrixF::Identity + //object->mountObjectToNode( objB, node, /*MatrixF::Identity*/txfm.getMatrix() ); + RotationF mat = object->getNodeTransform(node); + + return mat.asEulerF(RotationF::Degrees); + } + + return EulerF(0, 0, 0); +} + DefineEngineMethod(MeshComponent, getNodeByName, S32, (String nodeName), , "@brief Mount objB to this object at the desired slot with optional transform.\n\n" @@ -148,8 +170,14 @@ DefineEngineMethod(MeshComponent, getNodeByName, S32, return -1; } -DefineEngineMethod(MeshComponent, changeMaterial, void, (U32 slot, const char* newMat), (0, ""), +DefineEngineMethod(MeshComponent, changeMaterial, void, (U32 slot, MaterialAsset* newMat), (0, nullAsType()), "@brief Change one of the materials on the shape.\n\n") { object->changeMaterial(slot, newMat); +} + +DefineEngineMethod(MeshComponent, setMatInstField, bool, (U32 slot, const char* field, const char* value), (0, "", ""), + "@brief Change one of the materials on the shape.\n\n") +{ + return object->setMatInstField(slot, field, value); } \ No newline at end of file diff --git a/Engine/source/T3D/entity.cpp b/Engine/source/T3D/entity.cpp index d58d086c6..62c0b031f 100644 --- a/Engine/source/T3D/entity.cpp +++ b/Engine/source/T3D/entity.cpp @@ -47,7 +47,9 @@ #include "T3D/gameBase/std/stdMoveList.h" #include "T3D/prefab.h" +#include "T3D/gameBase/gameConnection.h" +#include // #include "gfx/sim/debugDraw.h" // @@ -118,6 +120,8 @@ Entity::Entity() mInitialized = false; + mLifetimeMS = 0; + mGameObjectAssetId = StringTable->insert(""); } @@ -147,6 +151,10 @@ void Entity::initPersistFields() endGroup("Transform"); + addGroup("Misc"); + addField("LifetimeMS", TypeS32, Offset(mLifetimeMS, Entity), "Object world orientation."); + endGroup("Misc"); + addGroup("GameObject"); addProtectedField("gameObjectName", TypeGameObjectAssetPtr, Offset(mGameObjectAsset, Entity), &_setGameObject, &defaultProtectedGetFn, "The asset Id used for the game object this entity is based on."); @@ -231,8 +239,19 @@ bool Entity::onAdd() addToScene(); //Make sure we get positioned - setMaskBits(TransformMask); - setMaskBits(NamespaceMask); + if (isServerObject()) + { + setMaskBits(TransformMask); + setMaskBits(NamespaceMask); + } + else + { + //We can shortcut the initialization here because stuff generally ghosts down in order, and onPostAdd isn't called on ghosts. + onPostAdd(); + } + + if (mLifetimeMS != 0) + mStartTimeMS = Platform::getRealMilliseconds(); return true; } @@ -245,6 +264,8 @@ void Entity::onRemove() onDataSet.removeAll(); + mGameObjectAsset.clear(); + Parent::onRemove(); } @@ -258,6 +279,27 @@ void Entity::onPostAdd() mComponents[i]->onComponentAdd(); } + //Set up the networked components + mNetworkedComponents.clear(); + for (U32 i = 0; i < mComponents.size(); i++) + { + if (mComponents[i]->isNetworked()) + { + NetworkedComponent netComp; + netComp.componentIndex = i; + netComp.updateState = NetworkedComponent::Adding; + netComp.updateMaskBits = -1; + + mNetworkedComponents.push_back(netComp); + } + } + + if (!mNetworkedComponents.empty()) + { + setMaskBits(AddComponentsMask); + setMaskBits(ComponentsUpdateMask); + } + if (isMethod("onAdd")) Con::executef(this, "onAdd"); } @@ -396,6 +438,14 @@ void Entity::processTick(const Move* move) mDelta.rot[1] = mRot.asQuatF(); setTransform(getPosition(), mRot); + + //Lifetime test + if (mLifetimeMS != 0) + { + S32 currentTime = Platform::getRealMilliseconds(); + if (currentTime - mStartTimeMS >= mLifetimeMS) + deleteObject(); + } } } @@ -446,62 +496,107 @@ U32 Entity::packUpdate(NetConnection *con, U32 mask, BitStream *stream) mathWrite(*stream, mObjBox); } - //pass our behaviors around - if (mask & ComponentsMask || mask & InitialUpdateMask) + if (stream->writeFlag(mask & AddComponentsMask)) { - stream->writeFlag(true); - //now, we run through a list of our to-be-sent behaviors and begin sending them - //if any fail, we keep our list and re-queue the mask - S32 componentCount = mToLoadComponents.size(); + U32 toAddComponentCount = 0; - //build our 'ready' list - //This requires both the instance and the instances' template to be prepped(if the template hasn't been ghosted, - //then we know we shouldn't be passing the instance's ghosts around yet) - U32 ghostedCompCnt = 0; - for (U32 i = 0; i < componentCount; i++) + for (U32 i = 0; i < mNetworkedComponents.size(); i++) { - if (con->getGhostIndex(mToLoadComponents[i]) != -1) - ghostedCompCnt++; - } - - if (ghostedCompCnt != 0) - { - stream->writeFlag(true); - - stream->writeFlag(mStartComponentUpdate); - - //if not all the behaviors have been ghosted, we'll need another pass - if (ghostedCompCnt != componentCount) - retMask |= ComponentsMask; - - //write the currently ghosted behavior count - stream->writeInt(ghostedCompCnt, 16); - - for (U32 i = 0; i < mToLoadComponents.size(); i++) + if (mNetworkedComponents[i].updateState == NetworkedComponent::Adding) { - //now fetch them and pass the ghost - S32 ghostIndex = con->getGhostIndex(mToLoadComponents[i]); - if (ghostIndex != -1) - { - stream->writeInt(ghostIndex, NetConnection::GhostIdBitSize); - mToLoadComponents.erase(i); - i--; - - mStartComponentUpdate = false; - } + toAddComponentCount++; } } - else if (componentCount) + + //you reaaaaally shouldn't have >255 networked components on a single entity + stream->writeInt(toAddComponentCount, 8); + + for (U32 i = 0; i < mNetworkedComponents.size(); i++) { - //on the odd chance we have behaviors to ghost, but NONE of them have been yet, just set the flag now - stream->writeFlag(false); - retMask |= ComponentsMask; + NetworkedComponent::UpdateState state = mNetworkedComponents[i].updateState; + + if (mNetworkedComponents[i].updateState == NetworkedComponent::Adding) + { + const char* className = mComponents[mNetworkedComponents[i].componentIndex]->getClassName(); + stream->writeString(className, strlen(className)); + + mNetworkedComponents[i].updateState = NetworkedComponent::Updating; + } } - else - stream->writeFlag(false); } - else - stream->writeFlag(false); + + if (stream->writeFlag(mask & RemoveComponentsMask)) + { + /*U32 toRemoveComponentCount = 0; + + for (U32 i = 0; i < mNetworkedComponents.size(); i++) + { + if (mNetworkedComponents[i].updateState == NetworkedComponent::Adding) + { + toRemoveComponentCount++; + } + } + + //you reaaaaally shouldn't have >255 networked components on a single entity + stream->writeInt(toRemoveComponentCount, 8); + + for (U32 i = 0; i < mNetworkedComponents.size(); i++) + { + if (mNetworkedComponents[i].updateState == NetworkedComponent::Removing) + { + stream->writeInt(i, 16); + } + }*/ + + /*for (U32 i = 0; i < mNetworkedComponents.size(); i++) + { + if (mNetworkedComponents[i].updateState == NetworkedComponent::UpdateState::Removing) + { + removeComponent(mComponents[mNetworkedComponents[i].componentIndex], true); + mNetworkedComponents.erase(i); + i--; + + } + }*/ + } + + //Update our components + if (stream->writeFlag(mask & ComponentsUpdateMask)) + { + U32 toUpdateComponentCount = 0; + + for (U32 i = 0; i < mNetworkedComponents.size(); i++) + { + if (mNetworkedComponents[i].updateState == NetworkedComponent::Updating) + { + toUpdateComponentCount++; + } + } + + //you reaaaaally shouldn't have >255 networked components on a single entity + stream->writeInt(toUpdateComponentCount, 8); + + bool forceUpdate = false; + + for (U32 i = 0; i < mNetworkedComponents.size(); i++) + { + if (mNetworkedComponents[i].updateState == NetworkedComponent::Updating) + { + stream->writeInt(i, 8); + + mNetworkedComponents[i].updateMaskBits = mComponents[mNetworkedComponents[i].componentIndex]->packUpdate(con, mNetworkedComponents[i].updateMaskBits, stream); + + if (mNetworkedComponents[i].updateMaskBits != 0) + forceUpdate = true; + else + mNetworkedComponents[i].updateState = NetworkedComponent::None; + } + } + + //If we have leftover, we need to re-iterate our packing + if (forceUpdate) + setMaskBits(ComponentsUpdateMask); + } /*if (stream->writeFlag(mask & NamespaceMask)) { @@ -594,25 +689,52 @@ void Entity::unpackUpdate(NetConnection *con, BitStream *stream) resetWorldBox(); } + //AddComponentMask if (stream->readFlag()) { - //are we passing any behaviors currently? - if (stream->readFlag()) + U32 addedComponentCount = stream->readInt(8); + + for (U32 i = 0; i < addedComponentCount; i++) { - //if we've just started the update, clear our behaviors - if (stream->readFlag()) - clearComponents(false); + char className[256] = ""; + stream->readString(className); - S32 componentCount = stream->readInt(16); + //Change to components, so iterate our list and create any new components + // Well, looks like we have to create a new object. + const char* componentType = className; - for (U32 i = 0; i < componentCount; i++) + ConsoleObject *object = ConsoleObject::create(componentType); + + // Finally, set currentNewObject to point to the new one. + Component* newComponent = dynamic_cast(object); + + if (newComponent) { - S32 gIndex = stream->readInt(NetConnection::GhostIdBitSize); - addComponent(dynamic_cast(con->resolveGhost(gIndex))); + addComponent(newComponent); } } } + //RemoveComponentMask + if (stream->readFlag()) + { + + } + + //ComponentUpdateMask + if (stream->readFlag()) + { + U32 updatingComponents = stream->readInt(8); + + for (U32 i = 0; i < updatingComponents; i++) + { + U32 updateComponentIndex = stream->readInt(8); + + Component* comp = mComponents[updateComponentIndex]; + comp->unpackUpdate(con, stream); + } + } + /*if (stream->readFlag()) { if (stream->readFlag()) @@ -640,6 +762,26 @@ void Entity::unpackUpdate(NetConnection *con, BitStream *stream) }*/ } +void Entity::setComponentNetMask(Component* comp, U32 mask) +{ + setMaskBits(Entity::ComponentsUpdateMask); + + for (U32 i = 0; i < mNetworkedComponents.size(); i++) + { + U32 netCompId = mComponents[mNetworkedComponents[i].componentIndex]->getId(); + U32 compId = comp->getId(); + + if (netCompId == compId && + (mNetworkedComponents[i].updateState == NetworkedComponent::None || mNetworkedComponents[i].updateState == NetworkedComponent::Updating)) + { + mNetworkedComponents[i].updateState = NetworkedComponent::Updating; + mNetworkedComponents[i].updateMaskBits |= mask; + + break; + } + } +} + //Manipulation void Entity::setTransform(const MatrixF &mat) { @@ -708,7 +850,7 @@ void Entity::setTransform(const MatrixF &mat) } } -void Entity::setTransform(Point3F position, RotationF rotation) +void Entity::setTransform(const Point3F& position, const RotationF& rotation) { MatrixF oldTransform = getTransform(); @@ -758,7 +900,11 @@ void Entity::setTransform(Point3F position, RotationF rotation) // Update the transforms. Parent::setTransform(newMat); - onTransformSet.trigger(&newMat); + U32 compCount = mComponents.size(); + for (U32 i = 0; i < compCount; ++i) + { + mComponents[i]->ownerTransformSet(&newMat); + } Point3F newPos = newMat.getPosition(); RotationF newRot = newMat; @@ -776,7 +922,7 @@ void Entity::setRenderTransform(const MatrixF &mat) Parent::setRenderTransform(mat); } -void Entity::setRenderTransform(Point3F position, RotationF rotation) +void Entity::setRenderTransform(const Point3F& position, const RotationF& rotation) { if (isMounted()) { @@ -800,7 +946,11 @@ void Entity::setRenderTransform(Point3F position, RotationF rotation) Parent::setRenderTransform(newMat); - onTransformSet.trigger(&newMat); + U32 compCount = mComponents.size(); + for (U32 i = 0; i < compCount; ++i) + { + mComponents[i]->ownerTransformSet(&newMat); + } } } @@ -827,7 +977,7 @@ MatrixF Entity::getTransform() } } -void Entity::setMountOffset(Point3F posOffset) +void Entity::setMountOffset(const Point3F& posOffset) { if (isMounted()) { @@ -837,7 +987,7 @@ void Entity::setMountOffset(Point3F posOffset) } } -void Entity::setMountRotation(EulerF rotOffset) +void Entity::setMountRotation(const EulerF& rotOffset) { if (isMounted()) { @@ -961,11 +1111,12 @@ bool Entity::castRayRendered(const Point3F &start, const Point3F &end, RayInfo * bool Entity::buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF &sphere) { - Vector updaters = getComponents(); + Con::errorf("Build Poly List not yet implemented as a passthrough for Entity"); + /*Vector updaters = getComponents(); for (Vector::iterator it = updaters.begin(); it != updaters.end(); it++) { return (*it)->buildPolyList(context, polyList, box, sphere); - } + }*/ return false; } @@ -981,7 +1132,7 @@ void Entity::buildConvex(const Box3F& box, Convex* convex) // // Mounting and heirarchy manipulation -void Entity::mountObject(SceneObject* objB, MatrixF txfm) +void Entity::mountObject(SceneObject* objB, const MatrixF& txfm) { Parent::mountObject(objB, -1, txfm); Parent::addObject(objB); @@ -1155,11 +1306,28 @@ bool Entity::addComponent(Component *comp) // Register the component with this owner. comp->setOwner(this); + comp->setIsServerObject(isServerObject()); + //if we've already been added and this is being added after the fact(at runtime), //then just go ahead and call it's onComponentAdd so it can get to work - if (mInitialized) + //if (mInitialized) + { comp->onComponentAdd(); + if (comp->isNetworked()) + { + NetworkedComponent netComp; + netComp.componentIndex = mComponents.size() - 1; + netComp.updateState = NetworkedComponent::Adding; + netComp.updateMaskBits = -1; + + mNetworkedComponents.push_back(netComp); + + setMaskBits(AddComponentsMask); + setMaskBits(ComponentsUpdateMask); + } + } + onComponentAdded.trigger(comp); return true; @@ -1269,7 +1437,7 @@ Component *Entity::getComponent(String componentType) Namespace *NS = comp->getNamespace(); //we shouldn't ever go past Component into net object, as we're no longer dealing with component classes - while (dStrcmp(NS->getName(), "NetObject")) + while (dStrcmp(NS->getName(), "SimObject")) { String namespaceName = NS->getName(); @@ -1437,7 +1605,7 @@ void Entity::onCameraScopeQuery(NetConnection* connection, CameraScopeQuery* que } } // -void Entity::setObjectBox(Box3F objBox) +void Entity::setObjectBox(const Box3F& objBox) { mObjBox = objBox; resetWorldBox(); @@ -1497,7 +1665,8 @@ void Entity::notifyComponents(String signalFunction, String argA, String argB, S void Entity::setComponentsDirty() { - if (mToLoadComponents.empty()) + bool tmp = true; + /*if (mToLoadComponents.empty()) mStartComponentUpdate = true; //we need to build a list of behaviors that need to be pushed across the network @@ -1522,7 +1691,7 @@ void Entity::setComponentsDirty() } } - setMaskBits(ComponentsMask); + setMaskBits(ComponentsMask);*/ } void Entity::setComponentDirty(Component *comp, bool forceUpdate) @@ -1537,8 +1706,8 @@ void Entity::setComponentDirty(Component *comp, bool forceUpdate) } } - if (!found) - return; + //if (!found) + // return; //if(mToLoadComponents.empty()) // mStartComponentUpdate = true; @@ -1654,7 +1823,7 @@ ConsoleMethod(Entity, addComponents, void, 2, 2, "() - Add all fielded behaviors object->addComponents(); }*/ -ConsoleMethod(Entity, addComponent, bool, 3, 3, "(Component* bi) - Add a behavior to the object\n" +ConsoleMethod(Entity, addComponent, bool, 3, 3, "(ComponentInstance bi) - Add a behavior to the object\n" "@param bi The behavior instance to add" "@return (bool success) Whether or not the behavior was successfully added") { @@ -1679,7 +1848,7 @@ ConsoleMethod(Entity, addComponent, bool, 3, 3, "(Component* bi) - Add a behavio return false; } -ConsoleMethod(Entity, removeComponent, bool, 3, 4, "(Component* bi, [bool deleteBehavior = true])\n" +ConsoleMethod(Entity, removeComponent, bool, 3, 4, "(ComponentInstance bi, [bool deleteBehavior = true])\n" "@param bi The behavior instance to remove\n" "@param deleteBehavior Whether or not to delete the behavior\n" "@return (bool success) Whether the behavior was successfully removed") @@ -1834,4 +2003,43 @@ DefineConsoleMethod(Entity, notify, void, (String signalFunction, String argA, S return; object->notifyComponents(signalFunction, argA, argB, argC, argD, argE); +} + +DefineConsoleFunction(findEntitiesByTag, const char*, (SimGroup* searchingGroup, String tags), (nullAsType(), ""), +"Finds all entities that have the provided tags.\n" +"@param searchingGroup The SimGroup to search inside. If null, we'll search the entire dictionary(this can be slow!).\n" +"@param tags Word delimited list of tags to search for. If multiple tags are included, the list is eclusively parsed, requiring all tags provided to be found on an entity for a match.\n" +"@return A word list of IDs of entities that match the tag search terms.") +{ + //if (tags.isEmpty()) + return ""; + + /*if (searchingGroup == nullptr) + { + searchingGroup = Sim::getRootGroup(); + } + + StringTableEntry entityStr = StringTable->insert("Entity"); + + std::thread threadBob; + + std::thread::id a = threadBob.get_id(); + std::thread::id b = std::this_thread::get_id().; + + if (a == b) + { + //do + } + + for (SimGroup::iterator itr = searchingGroup->begin(); itr != searchingGroup->end(); itr++) + { + Entity* ent = dynamic_cast((*itr)); + + if (ent != nullptr) + { + ent->mTags. + } + } + + object->notifyComponents(signalFunction, argA, argB, argC, argD, argE);*/ } \ No newline at end of file diff --git a/Engine/source/T3D/entity.h b/Engine/source/T3D/entity.h index 1f160e5a9..5bf9898ea 100644 --- a/Engine/source/T3D/entity.h +++ b/Engine/source/T3D/entity.h @@ -58,7 +58,27 @@ private: Vector mComponents; - Vector mToLoadComponents; + //Bit of helper data to let us track and manage the adding, removal and updating of networked components + struct NetworkedComponent + { + U32 componentIndex; + + enum UpdateState + { + None, + Adding, + Removing, + Updating + }; + + UpdateState updateState; + + U32 updateMaskBits; + }; + + Vector mNetworkedComponents; + + U32 mComponentNetMask; bool mStartComponentUpdate; @@ -69,10 +89,12 @@ private: bool mInitialized; + String mTags; + Signal< void(Component*) > onComponentAdded; Signal< void(Component*) > onComponentRemoved; - Signal< void(MatrixF*) > onTransformSet; + S32 mLifetimeMS; protected: @@ -105,10 +127,12 @@ public: { TransformMask = Parent::NextFreeMask << 0, BoundsMask = Parent::NextFreeMask << 1, - ComponentsMask = Parent::NextFreeMask << 2, - NoWarpMask = Parent::NextFreeMask << 3, - NamespaceMask = Parent::NextFreeMask << 4, - NextFreeMask = Parent::NextFreeMask << 5 + ComponentsUpdateMask = Parent::NextFreeMask << 2, + AddComponentsMask = Parent::NextFreeMask << 3, + RemoveComponentsMask = Parent::NextFreeMask << 4, + NoWarpMask = Parent::NextFreeMask << 5, + NamespaceMask = Parent::NextFreeMask << 6, + NextFreeMask = Parent::NextFreeMask << 7 }; StateDelta mDelta; @@ -116,6 +140,8 @@ public: Move lastMove; + S32 mStartTimeMS; + // Entity(); ~Entity(); @@ -126,14 +152,14 @@ public: virtual void setTransform(const MatrixF &mat); virtual void setRenderTransform(const MatrixF &mat); - void setTransform(Point3F position, RotationF rotation); + void setTransform(const Point3F& position, const RotationF& rotation); - void setRenderTransform(Point3F position, RotationF rotation); + void setRenderTransform(const Point3F& position, const RotationF& rotation); virtual MatrixF getTransform(); virtual Point3F getPosition() const { return mPos; } - void setRotation(RotationF rotation) { + void setRotation(const RotationF& rotation) { mRot = rotation; setMaskBits(TransformMask); }; @@ -141,8 +167,8 @@ public: static bool _setGameObject(void *object, const char *index, const char *data); - void setMountOffset(Point3F posOffset); - void setMountRotation(EulerF rotOffset); + void setMountOffset(const Point3F& posOffset); + void setMountRotation(const EulerF& rotOffset); //static bool _setEulerRotation( void *object, const char *index, const char *data ); static bool _setPosition(void *object, const char *index, const char *data); @@ -155,7 +181,7 @@ public: virtual void getRenderMountTransform(F32 delta, S32 index, const MatrixF &xfm, MatrixF *outMat); virtual void mountObject(SceneObject *obj, S32 node, const MatrixF &xfm = MatrixF::Identity); - void mountObject(SceneObject* objB, MatrixF txfm); + void mountObject(SceneObject* objB, const MatrixF& txfm); void onMount(SceneObject *obj, S32 node); void onUnmount(SceneObject *obj, S32 node); @@ -163,6 +189,9 @@ public: /// @param client Client that is now controlling this object virtual void setControllingClient(GameConnection *client); + // + //Networking + // // NetObject U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream); void unpackUpdate(NetConnection *conn, BitStream *stream); @@ -170,6 +199,8 @@ public: void setComponentsDirty(); void setComponentDirty(Component *comp, bool forceUpdate = false); + void setComponentNetMask(Component* comp, U32 mask); + //Components virtual bool deferAddingComponents() const { return true; } @@ -187,7 +218,7 @@ public: return mComponents.size(); } - virtual void setObjectBox(Box3F objBox); + virtual void setObjectBox(const Box3F& objBox); void resetWorldBox() { Parent::resetWorldBox(); } void resetObjectBox() { Parent::resetObjectBox(); } diff --git a/Engine/source/T3D/systems/componentSystem.h b/Engine/source/T3D/systems/componentSystem.h new file mode 100644 index 000000000..fc106a6a2 --- /dev/null +++ b/Engine/source/T3D/systems/componentSystem.h @@ -0,0 +1,30 @@ +#pragma once +#include "console/engineAPI.h" + +template +class SystemInterface +{ +public: + bool mIsEnabled; + bool mIsServer; + + static Vector all; + + SystemInterface() + { + all.push_back((T*)this); + } + + virtual ~SystemInterface() + { + for (U32 i = 0; i < all.size(); i++) + { + if (all[i] == (T*)this) + { + all.erase(i); + return; + } + } + } +}; +template Vector SystemInterface::all(0); \ No newline at end of file diff --git a/Engine/source/T3D/systems/render/meshRenderSystem.cpp b/Engine/source/T3D/systems/render/meshRenderSystem.cpp new file mode 100644 index 000000000..fe1ec6f84 --- /dev/null +++ b/Engine/source/T3D/systems/render/meshRenderSystem.cpp @@ -0,0 +1,378 @@ +#include "T3D/systems/render/meshRenderSystem.h" +#include "gfx/gfxTransformSaver.h" +#include "lighting/lightQuery.h" + +#include "renderInstance/renderPassManager.h" +#include "materials/materialManager.h" +#include "materials/baseMatInstance.h" + +Vector MeshRenderSystem::mBufferMaterials(0); +Vector MeshRenderSystem::mStaticBuffers(0); + +void MeshRenderSystem::render(SceneManager *sceneManager, SceneRenderState* state) +{ + if (sceneManager == nullptr || state == nullptr) + return; + + Frustum viewFrustum = state->getCullingFrustum(); + MatrixF camTransform = state->getCameraTransform(); + + U32 count = MeshRenderSystemInterface::all.size(); + for (U32 i = 0; i < count; i++) + { + //Server side items exist for data, but we don't actually render them + bool isClient = MeshRenderSystemInterface::all[i]->mIsClient; + if (!MeshRenderSystemInterface::all[i]->mIsClient) + continue; + + bool isStatic = MeshRenderSystemInterface::all[i]->mStatic; + if (MeshRenderSystemInterface::all[i]->mStatic) + continue; + + //First, do frustum culling + if (viewFrustum.isCulled(MeshRenderSystemInterface::all[i]->mBounds)) + continue; + + // Set the query box for the container query. Never + // make it larger than the frustum's AABB. In the editor, + // always query the full frustum as that gives objects + // the opportunity to render editor visualizations even if + // they are otherwise not in view. + if (!state->getCullingFrustum().getBounds().isOverlapped(state->getRenderArea())) + { + // This handles fringe cases like flying backwards into a zone where you + // end up pretty much standing on a zone border and looking directly into + // its "walls". In that case the traversal area will be behind the frustum + // (remember that the camera isn't where visibility starts, it's the near + // distance). + + continue; + } + + //We can then sort our objects by range since we have it already, so we can do occlusion culling be rendering front-to-back + + //if we've made it this far, call down to the render function to actually display our stuff + renderInterface(i, state); + } + + //Static Batch rendering + if ( /*!mMaterialInst ||*/ !state) + return; + + BaseMatInstance *matInst = MATMGR->getWarningMatInstance(); + + // Get a handy pointer to our RenderPassmanager + RenderPassManager *renderPass = state->getRenderPass(); + + for (U32 i = 0; i < mStaticBuffers.size(); i++) + { + for (U32 b = 0; b < mStaticBuffers[i].buffers.size(); b++) + { + if (mStaticBuffers[i].buffers[b].vertData.empty()) + continue; + + MeshRenderInst *ri = renderPass->allocInst(); + + // Set our RenderInst as a standard mesh render + ri->type = RenderPassManager::RIT_Mesh; + + //If our material has transparency set on this will redirect it to proper render bin + if (matInst->getMaterial()->isTranslucent()) + { + ri->type = RenderPassManager::RIT_Translucent; + ri->translucentSort = true; + } + + // Calculate our sorting point + if (state) + { + // Calculate our sort point manually. + const Box3F& rBox = Box3F(1000);// getRenderWorldBox(); + ri->sortDistSq = rBox.getSqDistanceToPoint(state->getCameraPosition()); + } + else + ri->sortDistSq = 0.0f; + + // Set up our transforms + MatrixF objectToWorld = MatrixF::Identity;//getRenderTransform(); + //objectToWorld.scale(getScale()); + + ri->objectToWorld = renderPass->allocUniqueXform(objectToWorld); + ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View); + ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection); + + // If our material needs lights then fill the RIs + // light vector with the best lights. + /*if (matInst->isForwardLit()) + { + LightQuery query; + query.init(getWorldSphere()); + query.getLights(ri->lights, 8); + }*/ + + // Make sure we have an up-to-date backbuffer in case + // our Material would like to make use of it + // NOTICE: SFXBB is removed and refraction is disabled! + //ri->backBuffTex = GFX->getSfxBackBuffer(); + + // Set our Material + ri->matInst = matInst; + + // Set up our vertex buffer and primitive buffer + ri->vertBuff = &mStaticBuffers[i].buffers[b].vertexBuffer; + ri->primBuff = &mStaticBuffers[i].buffers[b].primitiveBuffer; + + ri->prim = renderPass->allocPrim(); + ri->prim->type = GFXTriangleList; + ri->prim->minIndex = 0; + ri->prim->startIndex = 0; + ri->prim->numPrimitives = mStaticBuffers[i].buffers[b].primData.size(); + ri->prim->startVertex = 0; + ri->prim->numVertices = mStaticBuffers[i].buffers[b].vertData.size(); + + // We sort by the material then vertex buffer + ri->defaultKey = matInst->getStateHint(); + ri->defaultKey2 = (uintptr_t)ri->vertBuff; + + // Submit our RenderInst to the RenderPassManager + state->getRenderPass()->addInst(ri); + } + } +} + +void MeshRenderSystem::renderInterface(U32 interfaceIndex, SceneRenderState* state) +{ + //Fetch + MeshRenderSystemInterface* interface = MeshRenderSystemInterface::all[interfaceIndex]; + + if (interface->mShapeInstance == nullptr) + return; + + Point3F cameraOffset; + interface->mTransform.getColumn(3, &cameraOffset); + cameraOffset -= state->getDiffuseCameraPosition(); + F32 dist = cameraOffset.len(); + if (dist < 0.01f) + dist = 0.01f; + + Point3F objScale = interface->mScale; + F32 invScale = (1.0f / getMax(getMax(objScale.x, objScale.y), objScale.z)); + + interface->mShapeInstance->setDetailFromDistance(state, dist * invScale); + + if (interface->mShapeInstance->getCurrentDetail() < 0) + return; + + GFXTransformSaver saver; + + // Set up our TS render state. + TSRenderState rdata; + rdata.setSceneState(state); + rdata.setFadeOverride(1.0f); + rdata.setOriginSort(false); + + // We might have some forward lit materials + // so pass down a query to gather lights. + LightQuery query; + query.init(interface->mSphere); + rdata.setLightQuery(&query); + + MatrixF mat = interface->mTransform; + + mat.scale(objScale); + GFX->setWorldMatrix(mat); + + interface->mShapeInstance->render(rdata); +} + +void MeshRenderSystem::rebuildBuffers() +{ + U32 BUFFER_SIZE = 65000; + Vector tempIndices; + tempIndices.reserve(4); + + Box3F newBounds = Box3F::Zero; + + mStaticBuffers.clear(); + + for (U32 i = 0; i < MeshRenderSystemInterface::all.size(); i++) + { + if (!MeshRenderSystemInterface::all[i]->mIsEnabled) + continue; + + if (!MeshRenderSystemInterface::all[i]->mIsClient || !MeshRenderSystemInterface::all[i]->mStatic) + continue; + + //TODO: Properly re-implement StaticElements to container owner interfaces and buffer sets + for (U32 j = 0; j < MeshRenderSystemInterface::all[i]->mGeometry.mPolyList.size(); j++) + { + const OptimizedPolyList::Poly& poly = MeshRenderSystemInterface::all[i]->mGeometry.mPolyList[j]; + + if (poly.vertexCount < 3) + continue; + + tempIndices.setSize(poly.vertexCount); + dMemset(tempIndices.address(), 0, poly.vertexCount); + + if (poly.type == OptimizedPolyList::TriangleStrip || + poly.type == OptimizedPolyList::TriangleFan) + { + tempIndices[0] = 0; + U32 idx = 1; + + for (U32 k = 1; k < poly.vertexCount; k += 2) + tempIndices[idx++] = k; + + for (U32 k = ((poly.vertexCount - 1) & (~0x1)); k > 0; k -= 2) + tempIndices[idx++] = k; + } + else if (poly.type == OptimizedPolyList::TriangleList) + { + for (U32 k = 0; k < poly.vertexCount; k++) + tempIndices[k] = k; + } + else + continue; + + //got our data, now insert it into the correct buffer! + S32 bufferId = findBufferSetByMaterial(poly.material); + + if (bufferId == -1) + { + //add a new buffer set if we didn't get a match! + BufferSet newSet; + newSet.surfaceMaterialId = poly.material; + + mStaticBuffers.push_back(newSet); + + bufferId = mStaticBuffers.size() - 1; + } + + //see if this would push us over our buffer size limit, if it is, make a new buffer for this set + if (mStaticBuffers[bufferId].buffers.last().vertData.size() + 3 > BUFFER_SIZE + || mStaticBuffers[bufferId].buffers.last().primData.size() + 1 > BUFFER_SIZE) + { + //yep, we'll overstep with this, so spool up a new buffer in this set + BufferSet::Buffers newBuffer = BufferSet::Buffers(); + mStaticBuffers[bufferId].buffers.push_back(newBuffer); + } + + const U32& firstIdx = MeshRenderSystemInterface::all[i]->mGeometry.mIndexList[poly.vertexStart]; + const OptimizedPolyList::VertIndex& firstVertIdx = MeshRenderSystemInterface::all[i]->mGeometry.mVertexList[firstIdx]; + + //Vector geomPoints = MeshRenderSystemInterface::all[i]->mGeometry.mPoints; + //Vector geomNormals = MeshRenderSystemInterface::all[i]->mGeometry.mNormals; + //Vector geoUVs = MeshRenderSystemInterface::all[i]->mGeometry.mUV0s; + + for (U32 k = 1; k < poly.vertexCount - 1; k++) + { + const U32& secondIdx = MeshRenderSystemInterface::all[i]->mGeometry.mIndexList[poly.vertexStart + tempIndices[k]]; + const U32& thirdIdx = MeshRenderSystemInterface::all[i]->mGeometry.mIndexList[poly.vertexStart + tempIndices[k + 1]]; + + const OptimizedPolyList::VertIndex& secondVertIdx = MeshRenderSystemInterface::all[i]->mGeometry.mVertexList[secondIdx]; + const OptimizedPolyList::VertIndex& thirdVertIdx = MeshRenderSystemInterface::all[i]->mGeometry.mVertexList[thirdIdx]; + + Point3F points[3]; + points[0] = MeshRenderSystemInterface::all[i]->mGeometry.mPoints[firstVertIdx.vertIdx]; + points[1] = MeshRenderSystemInterface::all[i]->mGeometry.mPoints[secondVertIdx.vertIdx]; + points[2] = MeshRenderSystemInterface::all[i]->mGeometry.mPoints[thirdVertIdx.vertIdx]; + + Point3F normals[3]; + normals[0] = MeshRenderSystemInterface::all[i]->mGeometry.mNormals[firstVertIdx.normalIdx]; + normals[1] = MeshRenderSystemInterface::all[i]->mGeometry.mNormals[secondVertIdx.normalIdx]; + normals[2] = MeshRenderSystemInterface::all[i]->mGeometry.mNormals[thirdVertIdx.normalIdx]; + + Point3F tangents[3]; + tangents[0] = mCross(points[1] - points[0], normals[0]); + tangents[1] = mCross(points[2] - points[1], normals[1]); + tangents[2] = mCross(points[0] - points[2], normals[2]); + + Point2F uvs[3]; + uvs[0] = MeshRenderSystemInterface::all[i]->mGeometry.mUV0s[firstVertIdx.uv0Idx]; + uvs[1] = MeshRenderSystemInterface::all[i]->mGeometry.mUV0s[secondVertIdx.uv0Idx]; + uvs[2] = MeshRenderSystemInterface::all[i]->mGeometry.mUV0s[thirdVertIdx.uv0Idx]; + + mStaticBuffers[bufferId].vertCount += 3; + mStaticBuffers[bufferId].primCount += 1; + + for (U32 v = 0; v < 3; ++v) + { + //Build the vert and store it to the buffers! + GFXVertexPNTT bufVert; + bufVert.point = points[v]; + bufVert.normal = normals[v]; + bufVert.tangent = tangents[v]; + bufVert.texCoord = uvs[v]; + + newBounds.extend(points[v]); + + mStaticBuffers[bufferId].buffers.last().vertData.push_back(bufVert); + + U32 vertPrimId = mStaticBuffers[bufferId].buffers.last().vertData.size() - 1; + mStaticBuffers[bufferId].buffers.last().primData.push_back(vertPrimId); + + mStaticBuffers[bufferId].center += points[v]; + } + } + } + } + + //Now, iterate through the organized data and turn them into renderable buffers + for (U32 i = 0; i < mStaticBuffers.size(); i++) + { + for (U32 b = 0; b < mStaticBuffers[i].buffers.size(); b++) + { + BufferSet::Buffers& buffers = mStaticBuffers[i].buffers[b]; + + //if there's no data to be had in this buffer, just skip it + if (buffers.vertData.empty()) + continue; + + buffers.vertexBuffer.set(GFX, buffers.vertData.size(), GFXBufferTypeStatic); + GFXVertexPNTT *pVert = buffers.vertexBuffer.lock(); + + for (U32 v = 0; v < buffers.vertData.size(); v++) + { + pVert->normal = buffers.vertData[v].normal; + pVert->tangent = buffers.vertData[v].tangent; + //pVert->color = buffers.vertData[v].color; + pVert->point = buffers.vertData[v].point; + pVert->texCoord = buffers.vertData[v].texCoord; + + pVert++; + } + + buffers.vertexBuffer.unlock(); + + // Allocate PB + buffers.primitiveBuffer.set(GFX, buffers.primData.size(), buffers.primData.size() / 3, GFXBufferTypeStatic); + + U16 *pIndex; + buffers.primitiveBuffer.lock(&pIndex); + + for (U16 i = 0; i < buffers.primData.size(); i++) + { + *pIndex = i; + pIndex++; + } + + buffers.primitiveBuffer.unlock(); + } + + mStaticBuffers[i].center /= mStaticBuffers[i].vertCount; + } + + //mObjBox = newBounds; + //resetWorldBox(); +} + +U32 MeshRenderSystem::findBufferSetByMaterial(U32 matId) +{ + for (U32 i = 0; i < mStaticBuffers.size(); i++) + { + if (mStaticBuffers[i].surfaceMaterialId == matId) + return i; + } + + return -1; +} diff --git a/Engine/source/T3D/systems/render/meshRenderSystem.h b/Engine/source/T3D/systems/render/meshRenderSystem.h new file mode 100644 index 000000000..4bc2269db --- /dev/null +++ b/Engine/source/T3D/systems/render/meshRenderSystem.h @@ -0,0 +1,207 @@ +#pragma once +#include "scene/sceneRenderState.h" +#include "T3D/systems/componentSystem.h" +#include "ts/tsShape.h" +#include "ts/tsShapeInstance.h" +#include "T3D/assets/ShapeAsset.h" +#include "T3D/assets/MaterialAsset.h" + +#ifndef _GFXVERTEXBUFFER_H_ +#include "gfx/gfxVertexBuffer.h" +#endif +#ifndef _GFXPRIMITIVEBUFFER_H_ +#include "gfx/gfxPrimitiveBuffer.h" +#endif +#ifndef _OPTIMIZEDPOLYLIST_H_ +#include "collision/optimizedPolyList.h" +#endif + +class MeshRenderSystemInterface : public SystemInterface +{ +public: + TSShapeInstance * mShapeInstance; + + MatrixF mTransform; + Point3F mScale; + Box3F mBounds; + SphereF mSphere; + + bool mIsClient; + + struct matMap + { + //MaterialAsset* matAsset; + String assetId; + U32 slot; + }; + + Vector mChangingMaterials; + Vector mMaterials; + + //Static geometry stuff + bool mStatic; + + OptimizedPolyList mGeometry; + + MeshRenderSystemInterface() : SystemInterface(), mShapeInstance(nullptr), mTransform(MatrixF::Identity), mScale(Point3F::One), mIsClient(false), mStatic(false) + { + mBounds = Box3F(1); + mSphere = SphereF(); + } + + ~MeshRenderSystemInterface() + { + //SAFE_DELETE(mShape); + SAFE_DELETE(mShapeInstance); + } +}; + +class MeshRenderSystem +{ +protected: + /*struct StaticBatchElement + { + SimObject* owner; + OptimizedPolyList geometry; + String batchName; + }; + + static Vector mStaticElements;*/ + + //We retain the pushed geometry data for rendering here. It's static(unless forced to change through editing or whatnot) + //so rendering the batches is real fast + struct BufferMaterials + { + // The name of the Material we will use for rendering + String mMaterialName; + // The actual Material instance + BaseMatInstance* mMaterialInst; + + BufferMaterials() + { + mMaterialName = ""; + mMaterialInst = NULL; + } + }; + + static Vector mBufferMaterials; + + struct BufferSet + { + U32 surfaceMaterialId; + + U32 vertCount; + U32 primCount; + + Point3F center; + + struct Buffers + { + U32 vertStart; + U32 primStart; + U32 vertCount; + U32 primCount; + + Vector vertData; + Vector primData; + + GFXVertexBufferHandle< GFXVertexPNTT > vertexBuffer; + GFXPrimitiveBufferHandle primitiveBuffer; + + Buffers() + { + vertStart = 0; + primStart = 0; + vertCount = 0; + primCount = 0; + + vertexBuffer = NULL; + primitiveBuffer = NULL; + } + }; + + Vector buffers; + + BufferSet() + { + Buffers newBuffer; + buffers.push_back(newBuffer); + + surfaceMaterialId = 0; + + vertCount = 0; + primCount = 0; + + center = Point3F::Zero; + } + }; + + static Vector mStaticBuffers; + +public: + /*virtual void prepRenderImage(SceneRenderState *state); + + bool setMeshAsset(const char* assetName); + + virtual TSShape* getShape() { if (mMeshAsset) return mMeshAsset->getShape(); else return NULL; } + virtual TSShapeInstance* getShapeInstance() { return mShapeInstance; } + + Resource getShapeResource() { return mMeshAsset->getShapeResource(); } + + void _onResourceChanged(const Torque::Path &path); + + virtual bool castRayRendered(const Point3F &start, const Point3F &end, RayInfo *info); + + void mountObjectToNode(SceneObject* objB, String node, MatrixF txfm); + + virtual void onDynamicModified(const char* slotName, const char* newValue); + + void changeMaterial(U32 slot, MaterialAsset* newMat); + bool setMatInstField(U32 slot, const char* field, const char* value); + + virtual void onInspect(); + virtual void onEndInspect(); + + virtual Vector getNodeTransforms() + { + Vector bob; + return bob; + } + + virtual void setNodeTransforms(Vector transforms) + { + return; + }*/ + + /*MeshRenderSystem() + { + + } + virtual ~MeshRenderSystem() + { + smInterfaceList.clear(); + } + + static MeshComponentInterface* GetNewInterface() + { + smInterfaceList.increment(); + + return &smInterfaceList.last(); + } + + static void RemoveInterface(T* q) + { + smInterfaceList.erase(q); + }*/ + + //Core render function, which does all the real work + static void render(SceneManager *sceneManager, SceneRenderState* state); + + //Render our particular interface's data + static void renderInterface(U32 interfaceIndex, SceneRenderState* state); + + //Static Batch rendering + static void rebuildBuffers(); + + static U32 findBufferSetByMaterial(U32 matId); +}; \ No newline at end of file diff --git a/Engine/source/T3D/systems/updateSystem.cpp b/Engine/source/T3D/systems/updateSystem.cpp new file mode 100644 index 000000000..128329365 --- /dev/null +++ b/Engine/source/T3D/systems/updateSystem.cpp @@ -0,0 +1,34 @@ +#include "T3D/systems/updateSystem.h" + +void UpdateSystem::processTick() +{ + for (U32 i = 0; i < UpdateSystemInterface::all.size(); i++) + { + if (UpdateSystemInterface::all[i]->mIsEnabled) + { + //do work + } + } +} + +void UpdateSystem::advanceTime(U32 _tickMS) +{ + for (U32 i = 0; i < UpdateSystemInterface::all.size(); i++) + { + if (UpdateSystemInterface::all[i]->mIsEnabled) + { + //do work + } + } +} + +void UpdateSystem::interpolateTick(U32 _deltaMS) +{ + for (U32 i = 0; i < UpdateSystemInterface::all.size(); i++) + { + if (UpdateSystemInterface::all[i]->mIsEnabled) + { + //do work + } + } +} \ No newline at end of file diff --git a/Engine/source/T3D/systems/updateSystem.h b/Engine/source/T3D/systems/updateSystem.h new file mode 100644 index 000000000..b7d24eb88 --- /dev/null +++ b/Engine/source/T3D/systems/updateSystem.h @@ -0,0 +1,16 @@ +#pragma once +#include "componentSystem.h" + +class UpdateSystemInterface : public SystemInterface +{ +public: + bool mIsEnabled; +}; + +class UpdateSystem +{ +public: + static void processTick(); + static void advanceTime(U32 _tickMS); + static void interpolateTick(U32 _deltaMS); +}; \ No newline at end of file diff --git a/Engine/source/assets/assetBase.cpp b/Engine/source/assets/assetBase.cpp index 85ec18834..39cd4115f 100644 --- a/Engine/source/assets/assetBase.cpp +++ b/Engine/source/assets/assetBase.cpp @@ -69,7 +69,7 @@ AssetBase::~AssetBase() // If the asset manager does not own the asset then we own the // asset definition so delete it. if (!getOwned()) - delete mpAssetDefinition; + SAFE_DELETE(mpAssetDefinition); } //----------------------------------------------------------------------------- diff --git a/Engine/source/assets/assetBase.h b/Engine/source/assets/assetBase.h index 8709c5474..73c6df1c0 100644 --- a/Engine/source/assets/assetBase.h +++ b/Engine/source/assets/assetBase.h @@ -62,6 +62,7 @@ class AssetBase : public SimObject typedef SimObject Parent; +protected: AssetManager* mpOwningAssetManager; bool mAssetInitialized; AssetDefinition* mpAssetDefinition; diff --git a/Engine/source/assets/assetManager.cpp b/Engine/source/assets/assetManager.cpp index 805c52c01..da610a895 100644 --- a/Engine/source/assets/assetManager.cpp +++ b/Engine/source/assets/assetManager.cpp @@ -61,6 +61,15 @@ #ifndef COMPONENTASSET_H #include "T3D/assets/ComponentAsset.h" #endif +#ifndef GUI_ASSET_H +#include "T3D/assets/GUIAsset.h" +#endif +#ifndef SCRIPT_ASSET_H +#include "T3D/assets/ScriptAsset.h" +#endif +#ifndef MATERIALASSET_H +#include "T3D/assets/MaterialAsset.h" +#endif // Script bindings. #include "assetManager_ScriptBinding.h" @@ -251,6 +260,18 @@ bool AssetManager::loadModuleAutoLoadAssets(ModuleDefinition* pModuleDefinition) { assetBase = mTaml.read(assetDef->mAssetBaseFilePath); } + else if (assetDef->mAssetType == StringTable->insert("GUIAsset")) + { + assetBase = mTaml.read(assetDef->mAssetBaseFilePath); + } + else if (assetDef->mAssetType == StringTable->insert("ScriptAsset")) + { + assetBase = mTaml.read(assetDef->mAssetBaseFilePath); + } + else if (assetDef->mAssetType == StringTable->insert("MaterialAsset")) + { + assetBase = mTaml.read(assetDef->mAssetBaseFilePath); + } //load the asset now if valid if (assetBase) @@ -2369,6 +2390,13 @@ S32 AssetManager::findAssetLooseFile( AssetQuery* pAssetQuery, const char* pLoos //----------------------------------------------------------------------------- +AssetManager::typeAssetDependsOnHash* AssetManager::getDependedOnAssets() +{ + // Find any asset dependencies. + return &mAssetDependsOn; +} +//----------------------------------------------------------------------------- + bool AssetManager::scanDeclaredAssets( const char* pPath, const char* pExtension, const bool recurse, ModuleDefinition* pModuleDefinition ) { // Debug Profiling. diff --git a/Engine/source/assets/assetManager.h b/Engine/source/assets/assetManager.h index a8ac792a2..9271ea534 100644 --- a/Engine/source/assets/assetManager.h +++ b/Engine/source/assets/assetManager.h @@ -73,15 +73,18 @@ class AssetManager : public SimObject, public ModuleCallbacks { private: typedef SimObject Parent; - typedef StringTableEntry typeAssetId; - typedef StringTableEntry typeAssetName; - typedef StringTableEntry typeReferenceFilePath; - typedef HashMap typeDeclaredAssetsHash; - typedef HashTable typeReferencedAssetsHash; - typedef HashTable typeAssetDependsOnHash; - typedef HashTable typeAssetIsDependedOnHash; - typedef HashMap typeAssetPtrRefreshHash; +public: + typedef StringTableEntry typeAssetId; + typedef StringTableEntry typeAssetName; + typedef StringTableEntry typeReferenceFilePath; + typedef HashMap typeDeclaredAssetsHash; + typedef HashTable typeReferencedAssetsHash; + typedef HashTable typeAssetDependsOnHash; + typedef HashTable typeAssetIsDependedOnHash; + typedef HashMap typeAssetPtrRefreshHash; + +private: /// Declared assets. typeDeclaredAssetsHash mDeclaredAssets; @@ -368,6 +371,8 @@ public: S32 findTaggedAssets( AssetQuery* pAssetQuery, const char* pAssetTagNames, const bool assetQueryAsSource = false ); S32 findAssetLooseFile( AssetQuery* pAssetQuery, const char* pLooseFile, const bool assetQueryAsSource = false ); + typeAssetDependsOnHash* getDependedOnAssets(); + /// Declare Console Object. DECLARE_CONOBJECT( AssetManager ); diff --git a/Engine/source/console/codeBlock.cpp b/Engine/source/console/codeBlock.cpp index 3f5c3f292..f8f814f5b 100644 --- a/Engine/source/console/codeBlock.cpp +++ b/Engine/source/console/codeBlock.cpp @@ -409,6 +409,8 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) U32 totSize = codeLength + lineBreakPairCount * 2; code = new U32[totSize]; + // 0xFF is used as a flag to help compress the bytecode. + // If detected, the bytecode is only a U8. for (i = 0; i < codeLength; i++) { U8 b; @@ -442,7 +444,11 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) { U32 ip; st.read(&ip); +#ifdef TORQUE_CPU_X64 + *(U64*)(code + ip) = (U64)ste; +#else code[ip] = *((U32 *)&ste); +#endif } } diff --git a/Engine/source/console/consoleObject.h b/Engine/source/console/consoleObject.h index 30682d7f4..914330647 100644 --- a/Engine/source/console/consoleObject.h +++ b/Engine/source/console/consoleObject.h @@ -1265,10 +1265,6 @@ inline bool& ConsoleObject::getDynamicGroupExpand() EnginePropertyTable _propTable( sizeof( _props ) / sizeof( _props[ 0 ] ) - 1, _props ); \ } } -/// Add an auto-doc for a class. -#define ConsoleDocClass( className, docString ) \ - CLASSDOC( className, docString ) - /// @} //------------------------------------------------------------------------------ diff --git a/Engine/source/console/engineTypes.h b/Engine/source/console/engineTypes.h index 321e39686..2217ee770 100644 --- a/Engine/source/console/engineTypes.h +++ b/Engine/source/console/engineTypes.h @@ -576,7 +576,7 @@ namespace _Private { uintptr_t( ( ( const char* ) &( ( ( ThisType* ) 16 )->fieldName ) ) - 16 ) // Artificial offset to avoid compiler warnings. /// -#define CLASSDOC( className, doc ) \ +#define ConsoleDocClass( className, doc ) \ template<> const char* EngineClassTypeInfo< className, className::_ClassBase >::smDocString = doc; diff --git a/Engine/source/gui/containers/guiDragAndDropCtrl.cpp b/Engine/source/gui/containers/guiDragAndDropCtrl.cpp index 027fda6c8..a4aebe34c 100644 --- a/Engine/source/gui/containers/guiDragAndDropCtrl.cpp +++ b/Engine/source/gui/containers/guiDragAndDropCtrl.cpp @@ -152,14 +152,24 @@ ConsoleDocClass( GuiDragAndDropControl, "@ingroup GuiUtil" ); +IMPLEMENT_CALLBACK(GuiDragAndDropControl, onControlDragCancelled, void, (), (), + "Called when the we cancel out of the drag and drop action.\n" + "@see GuiDragAndDropControl::onControlDragCancelled"); //----------------------------------------------------------------------------- +GuiDragAndDropControl::GuiDragAndDropControl() : mDeleteOnMouseUp(true), mUseWholeCanvas(false) +{ + +} void GuiDragAndDropControl::initPersistFields() { addField( "deleteOnMouseUp", TypeBool, Offset( mDeleteOnMouseUp, GuiDragAndDropControl ), "If true, the control deletes itself when the left mouse button is released.\n\n" "If at this point, the drag&drop control still contains its payload, it will be deleted along with the control." ); + + addField("useWholeCanvas", TypeBool, Offset(mUseWholeCanvas, GuiDragAndDropControl), + "If true, the control can be tested against ANY control active on the canvas instead of just the direct parent.\n\n"); Parent::initPersistFields(); } @@ -226,8 +236,10 @@ void GuiDragAndDropControl::onMouseUp(const GuiEvent& event) mouseUnlock(); GuiControl* target = findDragTarget( event.mousePoint, "onControlDropped" ); - if( target ) - target->onControlDropped_callback( dynamic_cast< GuiControl* >( at( 0 ) ), getDropPoint() ); + if (target) + target->onControlDropped_callback(dynamic_cast(at(0)), getDropPoint()); + else + onControlDragCancelled_callback(); if( mDeleteOnMouseUp ) deleteObject(); @@ -239,6 +251,13 @@ GuiControl* GuiDragAndDropControl::findDragTarget( Point2I mousePoint, const cha { // If there are any children and we have a parent. GuiControl* parent = getParent(); + + if (mUseWholeCanvas) + { + parent->setVisible(false); + parent = getRoot(); + } + if (size() && parent) { mVisible = false; @@ -252,6 +271,10 @@ GuiControl* GuiDragAndDropControl::findDragTarget( Point2I mousePoint, const cha dropControl = dropControl->getParent(); } } + + if(mUseWholeCanvas) + parent->setVisible(true); + return NULL; } diff --git a/Engine/source/gui/containers/guiDragAndDropCtrl.h b/Engine/source/gui/containers/guiDragAndDropCtrl.h index a8ef0e7b3..a9806a7ee 100644 --- a/Engine/source/gui/containers/guiDragAndDropCtrl.h +++ b/Engine/source/gui/containers/guiDragAndDropCtrl.h @@ -53,6 +53,8 @@ class GuiDragAndDropControl : public GuiControl /// If true, the control deletes itself when the left mouse button is released. bool mDeleteOnMouseUp; + bool mUseWholeCanvas; + /// Controls may want to react when they are dragged over, entered or exited. SimObjectPtr mLastTarget; @@ -65,7 +67,7 @@ class GuiDragAndDropControl : public GuiControl public: - GuiDragAndDropControl() {} + GuiDragAndDropControl(); void startDragging(Point2I offset = Point2I(0, 0)); @@ -81,6 +83,8 @@ class GuiDragAndDropControl : public GuiControl DECLARE_DESCRIPTION( "A special control that implements drag&drop behavior.\n" "The control will notify other controls as it moves across the canvas.\n" "Content can be attached through dynamic fields or child objects." ); + + DECLARE_CALLBACK(void, onControlDragCancelled, ()); }; #endif \ No newline at end of file diff --git a/Engine/source/gui/controls/guiTreeViewCtrl.cpp b/Engine/source/gui/controls/guiTreeViewCtrl.cpp index ca499a758..9d45147e1 100644 --- a/Engine/source/gui/controls/guiTreeViewCtrl.cpp +++ b/Engine/source/gui/controls/guiTreeViewCtrl.cpp @@ -2501,6 +2501,19 @@ const char * GuiTreeViewCtrl::getItemValue(S32 itemId) //----------------------------------------------------------------------------- +S32 GuiTreeViewCtrl::getItemAtPosition(Point2I position) +{ + BitSet32 hitFlags = 0; + Item* item; + + if (_hitTest(position, item, hitFlags)) + return item->mId; + else + return -1; +} + +//----------------------------------------------------------------------------- + bool GuiTreeViewCtrl::editItem( S32 itemId, const char* newText, const char* newValue ) { Item* item = getItem( itemId ); @@ -5550,3 +5563,11 @@ DefineEngineMethod( GuiTreeViewCtrl, clearFilterText, void, (),, { object->clearFilterText(); } + +DefineEngineMethod(GuiTreeViewCtrl, getItemAtPosition, S32, (Point2I position), (Point2I::Zero), + "Get the tree item at the passed in position.\n\n" + "@param position The position to check for what item is below it.\n" + "@return The id of the item under the position.") +{ + return object->getItemAtPosition(position); +} \ No newline at end of file diff --git a/Engine/source/gui/controls/guiTreeViewCtrl.h b/Engine/source/gui/controls/guiTreeViewCtrl.h index 91f842b3d..686e3ea61 100644 --- a/Engine/source/gui/controls/guiTreeViewCtrl.h +++ b/Engine/source/gui/controls/guiTreeViewCtrl.h @@ -513,6 +513,8 @@ class GuiTreeViewCtrl : public GuiArrayCtrl bool editItem( S32 itemId, const char* newText, const char* newValue ); bool markItem( S32 itemId, bool mark ); + + S32 getItemAtPosition(Point2I position); bool isItemSelected( S32 itemId ); diff --git a/Engine/source/gui/core/guiCanvas.cpp b/Engine/source/gui/core/guiCanvas.cpp index 82c0475f0..efb0674ea 100644 --- a/Engine/source/gui/core/guiCanvas.cpp +++ b/Engine/source/gui/core/guiCanvas.cpp @@ -133,7 +133,8 @@ GuiCanvas::GuiCanvas(): GuiControl(), mLastRenderMs(0), mPlatformWindow(NULL), mDisplayWindow(true), - mMenuBarCtrl(NULL) + mMenuBarCtrl(nullptr), + mMenuBackground(nullptr) { setBounds(0, 0, 640, 480); mAwake = true; @@ -276,8 +277,6 @@ bool GuiCanvas::onAdd() // Define the menu bar for this canvas (if any) Con::executef(this, "onCreateMenu"); - Sim::findObject("PlatformGenericMenubar", mMenuBarCtrl); - return parentRet; } @@ -298,25 +297,49 @@ void GuiCanvas::setMenuBar(SimObject *obj) mMenuBarCtrl = dynamic_cast(obj); //remove old menubar - if( oldMenuBar ) - Parent::removeObject( oldMenuBar ); + if (oldMenuBar) + { + Parent::removeObject(oldMenuBar); + Parent::removeObject(mMenuBackground); //also remove the modeless wrapper + } // set new menubar - if( mMenuBarCtrl ) - Parent::addObject(mMenuBarCtrl); + if (mMenuBarCtrl) + { + //Add a wrapper control so that the menubar sizes correctly + GuiControlProfile* profile; + Sim::findObject("GuiModelessDialogProfile", profile); + + if (!profile) + { + Con::errorf("GuiCanvas::setMenuBar: Unable to find the GuiModelessDialogProfile profile!"); + return; + } + + if (mMenuBackground == nullptr) + { + mMenuBackground = new GuiControl(); + mMenuBackground->registerObject(); + + mMenuBackground->setControlProfile(profile); + } + + mMenuBackground->addObject(mMenuBarCtrl); + + Parent::addObject(mMenuBackground); + } // update window accelerator keys if( oldMenuBar != mMenuBarCtrl ) { - StringTableEntry ste = StringTable->insert("menubar"); - GuiMenuBar* menu = NULL; - menu = !oldMenuBar ? NULL : dynamic_cast(oldMenuBar->findObjectByInternalName( ste, true)); - if( menu ) - menu->removeWindowAcceleratorMap( *getPlatformWindow()->getInputGenerator() ); + GuiMenuBar* oldMenu = dynamic_cast(oldMenuBar); + GuiMenuBar* newMenu = dynamic_cast(mMenuBarCtrl); - menu = !mMenuBarCtrl ? NULL : dynamic_cast(mMenuBarCtrl->findObjectByInternalName( ste, true)); - if( menu ) - menu->buildWindowAcceleratorMap( *getPlatformWindow()->getInputGenerator() ); + if(oldMenu) + oldMenu->removeWindowAcceleratorMap(*getPlatformWindow()->getInputGenerator()); + + if(newMenu) + newMenu->buildWindowAcceleratorMap(*getPlatformWindow()->getInputGenerator()); } } @@ -1633,27 +1656,26 @@ void GuiCanvas::maintainSizing() Point2I newPos = screenRect.point; // if menubar is active displace content gui control - if( mMenuBarCtrl && (ctrl == getContentControl()) ) - { - const SimObject *menu = mMenuBarCtrl->findObjectByInternalName( StringTable->insert("menubar"), true); + if (mMenuBarCtrl && (ctrl == getContentControl())) + { + /*const SimObject *menu = mMenuBarCtrl->findObjectByInternalName( StringTable->insert("menubar"), true); - if( !menu ) - continue; + if( !menu ) + continue; - AssertFatal( dynamic_cast(menu), ""); + AssertFatal( dynamic_cast(menu), "");*/ - const U32 yOffset = static_cast(menu)->getExtent().y; - newPos.y += yOffset; - newExt.y -= yOffset; + const U32 yOffset = static_cast(mMenuBarCtrl)->mMenubarHeight; + newPos.y += yOffset; + newExt.y -= yOffset; } - if(pos != newPos || ext != newExt) + if (pos != newPos || ext != newExt) { ctrl->resize(newPos, newExt); resetUpdateRegions(); } } - } void GuiCanvas::setupFences() diff --git a/Engine/source/gui/core/guiCanvas.h b/Engine/source/gui/core/guiCanvas.h index dfc98da38..f9f4a37af 100644 --- a/Engine/source/gui/core/guiCanvas.h +++ b/Engine/source/gui/core/guiCanvas.h @@ -198,6 +198,7 @@ protected: static CanvasSizeChangeSignal smCanvasSizeChangeSignal; GuiControl *mMenuBarCtrl; + GuiControl* mMenuBackground; public: DECLARE_CONOBJECT(GuiCanvas); @@ -210,6 +211,7 @@ public: virtual void onRemove(); void setMenuBar(SimObject *obj); + SimObject* getMenuBar() { return mMenuBarCtrl; } static void initPersistFields(); diff --git a/Engine/source/gui/editor/guiInspector.cpp b/Engine/source/gui/editor/guiInspector.cpp index 63e112c9e..4551d03e8 100644 --- a/Engine/source/gui/editor/guiInspector.cpp +++ b/Engine/source/gui/editor/guiInspector.cpp @@ -54,7 +54,8 @@ GuiInspector::GuiInspector() mOverDivider( false ), mMovingDivider( false ), mHLField( NULL ), - mShowCustomFields( true ) + mShowCustomFields( true ), + mComponentGroupTargetId(-1) { mPadding = 1; } @@ -620,7 +621,10 @@ void GuiInspector::refresh() else compName = comp->getComponentName(); - GuiInspectorGroup *compGroup = new GuiInspectorComponentGroup(compName, this, comp); + StringBuilder captionString; + captionString.format("%s [%i]", compName.c_str(), comp->getId()); + + GuiInspectorGroup *compGroup = new GuiInspectorComponentGroup(captionString.data(), this, comp); if (compGroup != NULL) { compGroup->registerObject(); diff --git a/Engine/source/gui/editor/guiMenuBar.cpp b/Engine/source/gui/editor/guiMenuBar.cpp index 688531a87..dc168436b 100644 --- a/Engine/source/gui/editor/guiMenuBar.cpp +++ b/Engine/source/gui/editor/guiMenuBar.cpp @@ -142,24 +142,11 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMenuItemSelect, void, ( S32 menuId, const char "@see GuiTickCtrl\n\n" ); -IMPLEMENT_CALLBACK( GuiMenuBar, onSubmenuSelect, void, ( S32 submenuId, const char* submenuText ),( submenuId, submenuText ), - "@brief Called whenever a submenu is selected.\n\n" - "@param submenuId Id of the selected submenu\n" - "@param submenuText Text of the selected submenu\n\n" - "@tsexample\n" - "GuiMenuBar::onSubmenuSelect(%this,%submenuId,%submenuText)\n" - "{\n" - " // Code to run when the callback occurs\n" - "}\n" - "@endtsexample\n\n" - "@see GuiTickCtrl\n\n" -); - //------------------------------------------------------------------------------ // console methods //------------------------------------------------------------------------------ -DefineEngineMethod( GuiMenuBar, clearMenus, void, (),, +/*DefineEngineMethod( GuiMenuBar, clearMenus, void, (),, "@brief Clears all the menus from the menu bar.\n\n" "@tsexample\n" "// Inform the GuiMenuBar control to clear all menus from itself.\n" @@ -818,14 +805,14 @@ GuiMenuBar::Menu *GuiMenuBar::findMenu(const char *menu) { U32 id = dAtoi(menu); for (U32 i = 0; i < mMenuList.size(); ++i) - if (id == mMenuList[i]->id) + if (id == mMenuList[i].id) return mMenuList[i]; return NULL; } else { for (U32 i = 0; i < mMenuList.size(); ++i) - if (!dStricmp(menu, mMenuList[i]->text)) + if (!dStricmp(menu, mMenuList[i].text)) return mMenuList[i]; return NULL; } @@ -1093,19 +1080,18 @@ void GuiMenuBar::clearSubmenuItems(MenuItem *menuitem) while(menuitem->submenu->firstMenuItem) removeSubmenuItem(menuitem, menuitem->submenu->firstMenuItem); } - +*/ //------------------------------------------------------------------------------ // initialization, input and render methods //------------------------------------------------------------------------------ GuiMenuBar::GuiMenuBar() { - mMenuList.clear(); + //mMenuList.clear(); menuBarDirty = true; mouseDownMenu = NULL; mouseOverMenu = NULL; mCurAcceleratorIndex = 0; - mBackground = NULL; mPadding = 0; mCheckmarkBitmapIndex = 0; // Default to the first image in the bitmap array for the check mark @@ -1114,21 +1100,28 @@ GuiMenuBar::GuiMenuBar() mVerticalMargin = 1; // Default number of pixels on the top and bottom of a menu's text mBitmapMargin = 2; // Default number of pixels between a menu's bitmap and text + mMenubarHeight = 20; + // Added: mouseDownSubmenu = NULL; mouseOverSubmenu = NULL; - mSubmenuBackground = NULL; - mSubmenuTextList = NULL; - mMouseOverCounter = 0; - mCountMouseOver = false; - mMouseHoverAmount = 30; + + mMouseInMenu = false; + setProcessTicks(false); } +void GuiMenuBar::onRemove() +{ + Parent::onRemove(); +} + void GuiMenuBar::initPersistFields() { addField("padding", TypeS32, Offset( mPadding, GuiMenuBar ),"Extra padding to add to the bounds of the control.\n"); + addField("menubarHeight", TypeS32, Offset(mMenubarHeight, GuiMenuBar), "Sets the height of the menubar when attached to the canvas.\n"); + Parent::initPersistFields(); } @@ -1153,52 +1146,75 @@ bool GuiMenuBar::onWake() return true; } -GuiMenuBar::Menu *GuiMenuBar::findHitMenu(Point2I mousePoint) +void GuiMenuBar::addObject(SimObject* object) +{ + PopupMenu* popup = dynamic_cast(object); + + if (!popup) + { + //if it's not a popup, handle it normally + Parent::addObject(object); + } + else + { + //otherwise, if it IS a popup, don't add it as a child object, but instead just insert it as a menu entry + insert(object, -1); + } +} + +GuiMenuBar::MenuEntry *GuiMenuBar::findHitMenu(Point2I mousePoint) { Point2I pos = globalToLocalCoord(mousePoint); for (U32 i = 0; i < mMenuList.size(); ++i) - if (mMenuList[i]->visible && mMenuList[i]->bounds.pointInRect(pos)) - return mMenuList[i]; + { + if (mMenuList[i].visible && mMenuList[i].bounds.pointInRect(pos)) + return &mMenuList[i]; + } + return NULL; } void GuiMenuBar::onPreRender() { + setHeight(mMenubarHeight); + Parent::onPreRender(); - if(menuBarDirty) + if (menuBarDirty) { menuBarDirty = false; U32 curX = mPadding; for (U32 i = 0; i < mMenuList.size(); ++i) { - if (!mMenuList[i]->visible) + if (!mMenuList[i].visible) continue; - // Bounds depends on if there is a bitmap to be drawn or not - if (mMenuList[i]->bitmapIndex == -1) - { - // Text only - mMenuList[i]->bounds.set(curX, 0, mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2)); - - } else - { - // Will the bitmap and text be draw? - if (!mMenuList[i]->drawBitmapOnly) + // Bounds depends on if there is a bitmap to be drawn or not + if (mMenuList[i].bitmapIndex == -1) { + // Text only + mMenuList[i].bounds.set(curX, 0, mProfile->mFont->getStrWidth(mMenuList[i].text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2)); + + } + else + { + // Will the bitmap and text be draw? + if (!mMenuList[i].drawBitmapOnly) + { // Draw the bitmap and the text RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); - mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); + mMenuList[i].bounds.set(curX, 0, bitmapBounds[mMenuList[i].bitmapIndex].extent.x + mProfile->mFont->getStrWidth(mMenuList[i].text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); - } else - { + } + else + { // Only the bitmap will be drawn RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); - mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); + mMenuList[i].bounds.set(curX, 0, bitmapBounds[mMenuList[i].bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); + } } - } - curX += mMenuList[i]->bounds.extent.x; + curX += mMenuList[i].bounds.extent.x; } mouseOverMenu = NULL; mouseDownMenu = NULL; @@ -1207,12 +1223,12 @@ void GuiMenuBar::onPreRender() void GuiMenuBar::checkMenuMouseMove(const GuiEvent &event) { - Menu *hit = findHitMenu(event.mousePoint); + MenuEntry *hit = findHitMenu(event.mousePoint); if(hit && hit != mouseDownMenu) { // gotta close out the current menu... - mTextList->setSelectedCell(Point2I(-1, -1)); - closeMenu(); + mouseDownMenu->popupMenu->hidePopup(); + mouseOverMenu = mouseDownMenu = hit; setUpdate(); onAction(); @@ -1221,87 +1237,63 @@ void GuiMenuBar::checkMenuMouseMove(const GuiEvent &event) void GuiMenuBar::onMouseMove(const GuiEvent &event) { - Menu *hit = findHitMenu(event.mousePoint); - if(hit != mouseOverMenu) - { - // If we need to, reset the mouse over menu counter and indicate - // that we should track it. - if(hit) - mMouseOverCounter = 0; - if(!mCountMouseOver) - { - // We've never started the counter, so start it. - if(hit) - mCountMouseOver = true; - } + MenuEntry *hit = findHitMenu(event.mousePoint); - mouseOverMenu = hit; + if (mouseDownMenu != nullptr && hit != nullptr) + { + //we have a standing click, so just update and go + mouseDownMenu = mouseOverMenu = hit; setUpdate(); + onAction(); + + return; } + + mouseOverMenu = hit; + setUpdate(); +} + +void GuiMenuBar::onMouseEnter(const GuiEvent &event) +{ + onMouseInMenu_callback(true); + mMouseInMenu = true; } void GuiMenuBar::onMouseLeave(const GuiEvent &event) { if(mouseOverMenu) setUpdate(); - mouseOverMenu = NULL; - // As we've left the control, don't track how long the mouse has been - // within it. - if(mCountMouseOver && mMouseOverCounter >= mMouseHoverAmount) - { - onMouseInMenu_callback(false); // Last parameter indicates if we've entered or left the menu - } - mCountMouseOver = false; - mMouseOverCounter = 0; + mouseOverMenu = NULL; + mMouseInMenu = false; } void GuiMenuBar::onMouseDragged(const GuiEvent &event) { - Menu *hit = findHitMenu(event.mousePoint); - - if(hit != mouseOverMenu) - { - // If we need to, reset the mouse over menu counter and indicate - // that we should track it. - if(hit) - mMouseOverCounter = 0; - if(!mCountMouseOver) - { - // We've never started the counter, so start it. - if(hit) - mCountMouseOver = true; - } - - mouseOverMenu = hit; - mouseDownMenu = hit; - setUpdate(); - onAction(); - } } void GuiMenuBar::onMouseDown(const GuiEvent &event) +{ +} + +void GuiMenuBar::onMouseUp(const GuiEvent &event) { mouseDownMenu = mouseOverMenu = findHitMenu(event.mousePoint); setUpdate(); onAction(); } -void GuiMenuBar::onMouseUp(const GuiEvent &event) -{ - mouseDownMenu = NULL; - setUpdate(); -} - void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) { - RectI ctrlRect(offset, getExtent()); + Point2I extent = getExtent(); + + RectI ctrlRect(offset, extent); GFXDrawUtil* drawUtil = GFX->getDrawUtil(); //if opaque, fill the update rect with the fill color if (mProfile->mOpaque) - drawUtil->drawRectFill(RectI(offset, getExtent()), mProfile->mFillColor); + drawUtil->drawRectFill(RectI(offset, extent), mProfile->mFillColor); //if there's a border, draw the border if (mProfile->mBorder) @@ -1309,63 +1301,65 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) for (U32 i = 0; i < mMenuList.size(); ++i) { - if (!mMenuList[i]->visible) + if (!mMenuList[i].visible) continue; + ColorI fontColor = mProfile->mFontColor; - RectI bounds = mMenuList[i]->bounds; + RectI bounds = mMenuList[i].bounds; bounds.point += offset; - + Point2I start; - start.x = mMenuList[i]->bounds.point.x + mHorizontalMargin; - start.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - mProfile->mFont->getHeight()) / 2; + start.x = mMenuList[i].bounds.point.x + mHorizontalMargin; + start.y = mMenuList[i].bounds.point.y + (mMenuList[i].bounds.extent.y - mProfile->mFont->getHeight()) / 2; - // Draw the border - if (mMenuList[i]->drawBorder) - { - RectI highlightBounds = bounds; - highlightBounds.inset(1,1); - if (mMenuList[i] == mouseDownMenu) - renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL ); - else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) - renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL); - } + // Draw the border + if (mMenuList[i].drawBorder) + { + RectI highlightBounds = bounds; + highlightBounds.inset(1, 1); + if (&mMenuList[i] == mouseDownMenu) + renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL); + else if (&mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) + renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL); + } - // Do we draw a bitmap? - if (mMenuList[i]->bitmapIndex != -1) - { - S32 index = mMenuList[i]->bitmapIndex * 3; - if (mMenuList[i] == mouseDownMenu) + // Do we draw a bitmap? + if (mMenuList[i].bitmapIndex != -1) + { + S32 index = mMenuList[i].bitmapIndex * 3; + if (&mMenuList[i] == mouseDownMenu) ++index; - else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) + else if (&mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) index += 2; RectI rect = mProfile->mBitmapArrayRects[index]; - Point2I bitmapstart(start); - bitmapstart.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - rect.extent.y) / 2; + Point2I bitmapstart(start); + bitmapstart.y = mMenuList[i].bounds.point.y + (mMenuList[i].bounds.extent.y - rect.extent.y) / 2; drawUtil->clearBitmapModulation(); - drawUtil->drawBitmapSR( mProfile->mTextureObject, offset + bitmapstart, rect); + drawUtil->drawBitmapSR(mProfile->mTextureObject, offset + bitmapstart, rect); - // Should we also draw the text? - if (!mMenuList[i]->drawBitmapOnly) - { + // Should we also draw the text? + if (!mMenuList[i].drawBitmapOnly) + { start.x += mBitmapMargin; - drawUtil->setBitmapModulation( fontColor ); - drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors); - } - } else - { - drawUtil->setBitmapModulation( fontColor ); - drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors); - } + drawUtil->setBitmapModulation(fontColor); + drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i].text, mProfile->mFontColors); + } + } + else + { + drawUtil->setBitmapModulation(fontColor); + drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i].text, mProfile->mFontColors); + } } - renderChildControls( offset, updateRect ); + renderChildControls(offset, updateRect); } -void GuiMenuBar::buildWindowAcceleratorMap( WindowInputGenerator &inputGenerator ) +void GuiMenuBar::buildWindowAcceleratorMap(WindowInputGenerator &inputGenerator) { // ok, accelerator map is cleared... // add all our keys: @@ -1373,20 +1367,21 @@ void GuiMenuBar::buildWindowAcceleratorMap( WindowInputGenerator &inputGenerator for (U32 i = 0; i < mMenuList.size(); ++i) { - for (MenuItem *item = mMenuList[i]->firstMenuItem; item; item = item->nextMenuItem) + for (U32 item = 0; item < mMenuList[i].popupMenu->mMenuItems.size(); item++) { - if(!item->accelerator) + if (!mMenuList[i].popupMenu->mMenuItems[item].accelerator) { - item->accelerator = 0; + mMenuList[i].popupMenu->mMenuItems[item].accelerator = 0; continue; } - EventDescriptor accelEvent; - ActionMap::createEventDescriptor(item->accelerator, &accelEvent); - - //now we have a modifier, and a key, add them to the canvas - inputGenerator.addAcceleratorKey( this, item->cmd, accelEvent.eventCode, accelEvent.flags); - item->acceleratorIndex = mCurAcceleratorIndex; + EventDescriptor accelEvent; + ActionMap::createEventDescriptor(mMenuList[i].popupMenu->mMenuItems[item].accelerator, &accelEvent); + + //now we have a modifier, and a key, add them to the canvas + inputGenerator.addAcceleratorKey(this, mMenuList[i].popupMenu->mMenuItems[item].cmd, accelEvent.eventCode, accelEvent.flags); + + mMenuList[i].popupMenu->mMenuItems[item].acceleratorIndex = mCurAcceleratorIndex; mCurAcceleratorIndex++; } } @@ -1403,591 +1398,134 @@ void GuiMenuBar::acceleratorKeyPress(U32 index) // and find the item that corresponds to the accelerator index for (U32 i = 0; i < mMenuList.size(); ++i) { - if (!mMenuList[i]->visible) + if (!mMenuList[i].visible) continue; - for (MenuItem *item = mMenuList[i]->firstMenuItem; item; item = item->nextMenuItem) + for(U32 item = 0; item < mMenuList[i].popupMenu->mMenuItems.size(); item++) { - if(item->acceleratorIndex == index) + if(mMenuList[i].popupMenu->mMenuItems[item].acceleratorIndex == index) { // first, call the script callback for menu selection: - onMenuSelect_callback(mMenuList[i]->id, mMenuList[i]->text); - - if(item->visible) - menuItemSelected(mMenuList[i], item); + onMenuSelect_callback(mMenuList[i].popupMenu->getId(), mMenuList[i].text); return; } } } } -//------------------------------------------------------------------------------ -// Menu display class methods -//------------------------------------------------------------------------------ - -GuiMenuBackgroundCtrl::GuiMenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl *textList) -{ - mMenuBarCtrl = ctrl; - mTextList = textList; -} - -void GuiMenuBackgroundCtrl::onMouseDown(const GuiEvent &event) -{ - mTextList->setSelectedCell(Point2I(-1,-1)); - mMenuBarCtrl->closeMenu(); -} - -void GuiMenuBackgroundCtrl::onMouseMove(const GuiEvent &event) -{ - GuiCanvas *root = getRoot(); - GuiControl *ctrlHit = root->findHitControl(event.mousePoint, mLayer - 1); - if(ctrlHit == mMenuBarCtrl) // see if the current mouse over menu is right... - mMenuBarCtrl->checkMenuMouseMove(event); -} - -void GuiMenuBackgroundCtrl::onMouseDragged(const GuiEvent &event) -{ - GuiCanvas *root = getRoot(); - GuiControl *ctrlHit = root->findHitControl(event.mousePoint, mLayer - 1); - if(ctrlHit == mMenuBarCtrl) // see if the current mouse over menu is right... - mMenuBarCtrl->checkMenuMouseMove(event); -} - -GuiMenuTextListCtrl::GuiMenuTextListCtrl(GuiMenuBar *ctrl) -{ - mMenuBarCtrl = ctrl; - isSubMenu = false; // Added -} - -void GuiMenuTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver) -{ - if(dStrcmp(mList[cell.y].text + 3, "-\t")) // Was: dStrcmp(mList[cell.y].text + 2, "-\t")) but has been changed to take into account the submenu flag - Parent::onRenderCell(offset, cell, selected, mouseOver); - else - { - S32 yp = offset.y + mCellSize.y / 2; - GFX->getDrawUtil()->drawLine(offset.x, yp, offset.x + mCellSize.x, yp, ColorI(128,128,128)); - GFX->getDrawUtil()->drawLine(offset.x, yp+1, offset.x + mCellSize.x, yp+1, ColorI(255,255,255)); - } - // now see if there's a bitmap... - U8 idx = mList[cell.y].text[0]; - if(idx != 1) - { - // there's a bitmap... - U32 index = U32(idx - 2) * 3; - if(!mList[cell.y].active) - index += 2; - else if(selected || mouseOver) - index ++; - - RectI rect = mProfile->mBitmapArrayRects[index]; - Point2I off = mMenuBarCtrl->maxBitmapSize - rect.extent; - off /= 2; - - GFX->getDrawUtil()->clearBitmapModulation(); - GFX->getDrawUtil()->drawBitmapSR(mProfile->mTextureObject, offset + off, rect); - } - - // Check if this is a submenu - idx = mList[cell.y].text[1]; - if(idx != 1) - { - // This is a submenu, so draw an arrow - S32 left = offset.x + mCellSize.x - 12; - S32 right = left + 8; - S32 top = mCellSize.y / 2 + offset.y - 4; - S32 bottom = top + 8; - S32 middle = top + 4; - - PrimBuild::begin( GFXTriangleList, 3 ); - if( selected || mouseOver ) - PrimBuild::color( mProfile->mFontColorHL ); - else - PrimBuild::color( mProfile->mFontColor ); - - PrimBuild::vertex2i( left, top ); - PrimBuild::vertex2i( right, middle ); - PrimBuild::vertex2i( left, bottom ); - PrimBuild::end(); - } -} - -bool GuiMenuTextListCtrl::onKeyDown(const GuiEvent &event) -{ - //if the control is a dead end, don't process the input: - if ( !mVisible || !mActive || !mAwake ) - return false; - - //see if the key down is a or not - if ( event.modifier == 0 ) - { - if ( event.keyCode == KEY_RETURN ) - { - mMenuBarCtrl->closeMenu(); - return true; - } - else if ( event.keyCode == KEY_ESCAPE ) - { - mSelectedCell.set( -1, -1 ); - mMenuBarCtrl->closeMenu(); - return true; - } - } - - //otherwise, pass the event to it's parent - return Parent::onKeyDown(event); -} - -void GuiMenuTextListCtrl::onMouseDown(const GuiEvent &event) -{ - Parent::onMouseDown(event); -} - -void GuiMenuTextListCtrl::onMouseUp(const GuiEvent &event) -{ - Parent::onMouseUp(event); - mMenuBarCtrl->closeMenu(); -} - -void GuiMenuTextListCtrl::onCellHighlighted(Point2I cell) -{ - // If this text list control is part of a submenu, then don't worry about - // passing this along - if(!isSubMenu) - { - RectI globalbounds(getBounds()); - Point2I globalpoint = localToGlobalCoord(globalbounds.point); - globalbounds.point = globalpoint; - mMenuBarCtrl->highlightedMenuItem(cell.y, globalbounds, mCellSize); - } -} - -//------------------------------------------------------------------------------ -// Submenu display class methods -//------------------------------------------------------------------------------ - -GuiSubmenuBackgroundCtrl::GuiSubmenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl *textList) : GuiMenuBackgroundCtrl(ctrl, textList) -{ -} - -void GuiSubmenuBackgroundCtrl::onMouseDown(const GuiEvent &event) -{ - mTextList->setSelectedCell(Point2I(-1,-1)); - mMenuBarCtrl->closeMenu(); -} - -bool GuiSubmenuBackgroundCtrl::pointInControl(const Point2I& parentCoordPoint) -{ - S32 xt = parentCoordPoint.x - getLeft(); - S32 yt = parentCoordPoint.y - getTop(); - - if(findHitControl(Point2I(xt,yt)) == this) - return false; - else - return true; -// return xt >= 0 && yt >= 0 && xt < getWidth() && yt < getHeight(); -} - -//------------------------------------------------------------------------------ - -void GuiMenuBar::menuItemSelected(GuiMenuBar::Menu *menu, GuiMenuBar::MenuItem *item) -{ - if(item->enabled) - onMenuItemSelect_callback(menu->id, menu->text, item->id, item->text); -} - void GuiMenuBar::onSleep() { - if(mBackground) // a menu is up? - { - mTextList->setSelectedCell(Point2I(-1, -1)); - closeMenu(); - } Parent::onSleep(); } -void GuiMenuBar::closeMenu() -{ - // First close any open submenu - closeSubmenu(); - - // Get the selection from the text list: - S32 selectionIndex = mTextList->getSelectedCell().y; - - // Pop the background: - if( getRoot() ) - getRoot()->popDialogControl(mBackground); - else - return; - - // Kill the popup: - mBackground->deleteObject(); - mBackground = NULL; - - // Now perform the popup action: - if ( selectionIndex != -1 ) - { - MenuItem *list = mouseDownMenu->firstMenuItem; - - while(selectionIndex && list) - { - list = list->nextMenuItem; - selectionIndex--; - } - if(list) - menuItemSelected(mouseDownMenu, list); - } - mouseDownMenu = NULL; -} - -// Called when a menu item is highlighted by the mouse -void GuiMenuBar::highlightedMenuItem(S32 selectionIndex, const RectI& bounds, Point2I cellSize) -{ - S32 selstore = selectionIndex; - - // Now perform the popup action: - if ( selectionIndex != -1 ) - { - MenuItem *list = mouseDownMenu->firstMenuItem; - - while(selectionIndex && list) - { - list = list->nextMenuItem; - selectionIndex--; - } - - if(list) - { - // If the highlighted item has changed... - if(mouseOverSubmenu != list) - { - closeSubmenu(); - mouseOverSubmenu = NULL; - - // Check if this is a submenu. If so, open the submenu. - if(list->isSubmenu) - { - // If there are submenu items, then open the submenu - if(list->submenu->firstMenuItem) - { - mouseOverSubmenu = list; - onSubmenuAction(selstore, bounds, cellSize); - } - } - } - } - } -} - //------------------------------------------------------------------------------ void GuiMenuBar::onAction() { if(!mouseDownMenu) return; - // first, call the script callback for menu selection: - onMenuSelect_callback(mouseDownMenu->id, mouseDownMenu->text); - - MenuItem *visWalk = mouseDownMenu->firstMenuItem; - while(visWalk) - { - if(visWalk->visible) - break; - visWalk = visWalk->nextMenuItem; - } - if(!visWalk) - { - mouseDownMenu = NULL; - return; - } - - mTextList = new GuiMenuTextListCtrl(this); - mTextList->setControlProfile(mProfile); - - mBackground = new GuiMenuBackgroundCtrl(this, mTextList); - - GuiCanvas *root = getRoot(); - Point2I windowExt = root->getExtent(); - - mBackground->resize( Point2I(0,0), root->getExtent()); - S32 textWidth = 0, width = 0; - S32 acceleratorWidth = 0; - - GFont *font = mProfile->mFont; - - for(MenuItem *walk = mouseDownMenu->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if(!walk->visible) - continue; - - S32 iTextWidth = font->getStrWidth(walk->text); - S32 iAcceleratorWidth = walk->accelerator ? font->getStrWidth(walk->accelerator) : 0; - - if(iTextWidth > textWidth) - textWidth = iTextWidth; - if(iAcceleratorWidth > acceleratorWidth) - acceleratorWidth = iAcceleratorWidth; - } - width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4; - - mTextList->setCellSize(Point2I(width, font->getHeight()+2)); - mTextList->clearColumnOffsets(); - mTextList->addColumnOffset(-1); // add an empty column in for the bitmap index. - mTextList->addColumnOffset(maxBitmapSize.x + 1); - mTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4); - - U32 entryCount = 0; - - for(MenuItem *walk = mouseDownMenu->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if(!walk->visible) - continue; - - char buf[512]; - - // If this menu item is a submenu, then set the isSubmenu to 2 to indicate - // an arrow should be drawn. Otherwise set the isSubmenu normally. - char isSubmenu = 1; - if(walk->isSubmenu) - isSubmenu = 2; - - char bitmapIndex = 1; - if(walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= mProfile->mBitmapArrayRects.size())) - bitmapIndex = walk->bitmapIndex + 2; - dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, walk->text, walk->accelerator ? walk->accelerator : ""); - mTextList->addEntry(entryCount, buf); - - if(!walk->enabled) - mTextList->setEntryActive(entryCount, false); - - entryCount++; - } - Point2I menuPoint = localToGlobalCoord(mouseDownMenu->bounds.point); - menuPoint.y += mouseDownMenu->bounds.extent.y; // Used to have this at the end: + 2; - - GuiControl *ctrl = new GuiControl; - RectI ctrlBounds( menuPoint, mTextList->getExtent() + Point2I(6, 6)); - - ctrl->setControlProfile(mProfile); - mTextList->setPosition( mTextList->getPosition() + Point2I(3,3) ); - - // Make sure the menu doesn't go beyond the Canvas' bottom edge. - if((ctrlBounds.point.y + ctrlBounds.extent.y) > windowExt.y) - { - // Pop the menu above the menu bar - Point2I menuBar = localToGlobalCoord(mouseDownMenu->bounds.point); - ctrlBounds.point.y = menuBar.y - ctrl->getHeight(); - } - - ctrl->resize(ctrlBounds.point, ctrlBounds.extent); - //mTextList->setPosition(Point2I(3,3)); - - mTextList->registerObject(); - mBackground->registerObject(); - ctrl->registerObject(); - - mBackground->addObject( ctrl ); - ctrl->addObject( mTextList ); - - root->pushDialogControl(mBackground, mLayer + 1); - mTextList->setFirstResponder(); -} - -//------------------------------------------------------------------------------ -// Performs an action when a menu item that is a submenu is selected/highlighted -void GuiMenuBar::onSubmenuAction(S32 selectionIndex, const RectI& bounds, Point2I cellSize) -{ - if(!mouseOverSubmenu) - return; + mouseDownMenu->popupMenu->hidePopup(); // first, call the script callback for menu selection: - onSubmenuSelect_callback(mouseOverSubmenu->id, mouseOverSubmenu->text); + onMenuSelect_callback(mouseDownMenu->popupMenu->getId(), mouseDownMenu->text); - MenuItem *visWalk = mouseOverSubmenu->submenu->firstMenuItem; - while(visWalk) - { - if(visWalk->visible) - break; - visWalk = visWalk->nextMenuItem; - } - if(!visWalk) - { - mouseOverSubmenu = NULL; - return; - } - - mSubmenuTextList = new GuiMenuTextListCtrl(this); - mSubmenuTextList->setControlProfile(mProfile); - mSubmenuTextList->isSubMenu = true; // Indicate that this text list is part of a submenu - - mSubmenuBackground = new GuiSubmenuBackgroundCtrl(this, mSubmenuTextList); + mouseDownMenu->popupMenu->mMenuBarCtrl = this; GuiCanvas *root = getRoot(); - Point2I windowExt = root->getExtent(); - - mSubmenuBackground->resize( Point2I(0,0), root->getExtent()); - S32 textWidth = 0, width = 0; - S32 acceleratorWidth = 0; - - GFont *font = mProfile->mFont; - - for(MenuItem *walk = mouseOverSubmenu->submenu->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if(!walk->visible) - continue; - - S32 iTextWidth = font->getStrWidth(walk->text); - S32 iAcceleratorWidth = walk->accelerator ? font->getStrWidth(walk->accelerator) : 0; - - if(iTextWidth > textWidth) - textWidth = iTextWidth; - if(iAcceleratorWidth > acceleratorWidth) - acceleratorWidth = iAcceleratorWidth; - } - width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4; - - mSubmenuTextList->setCellSize(Point2I(width, font->getHeight()+3)); - mSubmenuTextList->clearColumnOffsets(); - mSubmenuTextList->addColumnOffset(-1); // add an empty column in for the bitmap index. - mSubmenuTextList->addColumnOffset(maxBitmapSize.x + 1); - mSubmenuTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4); - - U32 entryCount = 0; - - for(MenuItem *walk = mouseOverSubmenu->submenu->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if(!walk->visible) - continue; - - char buf[512]; - - // Can't have submenus within submenus. - char isSubmenu = 1; - - char bitmapIndex = 1; - if(walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= mProfile->mBitmapArrayRects.size())) - bitmapIndex = walk->bitmapIndex + 2; - dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, walk->text, walk->accelerator ? walk->accelerator : ""); - mSubmenuTextList->addEntry(entryCount, buf); - - if(!walk->enabled) - mSubmenuTextList->setEntryActive(entryCount, false); - - entryCount++; - } - Point2I menuPoint = bounds.point; //localToGlobalCoord(bounds.point); - menuPoint.x += bounds.extent.x; - menuPoint.y += cellSize.y * selectionIndex - 6; - - GuiControl *ctrl = new GuiControl; - RectI ctrlBounds(menuPoint, mSubmenuTextList->getExtent() + Point2I(6, 6)); - ctrl->setControlProfile(mProfile); - mSubmenuTextList->setPosition( getPosition() + Point2I(3,3)); - - // Make sure the menu doesn't go beyond the Canvas' bottom edge. - if((ctrlBounds.point.y + ctrlBounds.extent.y ) > windowExt.y) - { - // Pop the menu above the menu bar - ctrlBounds.point.y -= mSubmenuTextList->getHeight() - cellSize.y - 6 - 3; - } - - // And the same for the right edge - if((ctrlBounds.point.x + ctrlBounds.extent.x) > windowExt.x) - { - // Pop the submenu to the left of the menu - ctrlBounds.point.x -= mSubmenuTextList->getWidth() + cellSize.x + 6; - } - ctrl->resize(ctrlBounds.point, ctrlBounds.extent); - - //mSubmenuTextList->setPosition(Point2I(3,3)); - - mSubmenuTextList->registerObject(); - mSubmenuBackground->registerObject(); - ctrl->registerObject(); - - mSubmenuBackground->addObject( ctrl ); - ctrl->addObject( mSubmenuTextList ); - - root->pushDialogControl(mSubmenuBackground, mLayer + 1); - mSubmenuTextList->setFirstResponder(); -} - -// Close down the submenu controls -void GuiMenuBar::closeSubmenu() -{ - if(!mSubmenuBackground || !mSubmenuTextList) - return; - - // Get the selection from the text list: - S32 selectionIndex = mSubmenuTextList->getSelectedCell().y; - - // Pop the background: - if( getRoot() ) - getRoot()->popDialogControl(mSubmenuBackground); - - // Kill the popup: - mSubmenuBackground->deleteObject(); - mSubmenuBackground = NULL; - mSubmenuTextList = NULL; - - // Now perform the popup action: - if ( selectionIndex != -1 ) - { - MenuItem *list = NULL; - if(mouseOverSubmenu) - { - list = mouseOverSubmenu->submenu->firstMenuItem; - - while(selectionIndex && list) - { - list = list->nextMenuItem; - selectionIndex--; - } - } - if(list) - menuItemSelected(list->submenuParentMenu, list); - } - mouseOverSubmenu = NULL; -} - -// Find if the mouse pointer is within a menu item -GuiMenuBar::MenuItem *GuiMenuBar::findHitMenuItem(Point2I mousePoint) -{ - -// for(Menu *walk = menuList; walk; walk = walk->nextMenu) -// if(walk->visible && walk->bounds.pointInRect(pos)) -// return walk; - return NULL; -} - -// Checks if the mouse has been moved to a new menu item -void GuiMenuBar::checkSubmenuMouseMove(const GuiEvent &event) -{ - MenuItem *hit = findHitMenuItem(event.mousePoint); - if(hit && hit != mouseOverSubmenu) - { - // gotta close out the current menu... - mSubmenuTextList->setSelectedCell(Point2I(-1, -1)); -// closeSubmenu(); - setUpdate(); - } + Point2I pos = Point2I(mouseDownMenu->bounds.point.x, mouseDownMenu->bounds.point.y + mouseDownMenu->bounds.extent.y); + mouseDownMenu->popupMenu->showPopup(root, pos.x, pos.y); } // Process a tick void GuiMenuBar::processTick() { - // If we are to track a tick, then do so. - if(mCountMouseOver) - { - // If we're at a particular number of ticks, notify the script function - if(mMouseOverCounter < mMouseHoverAmount) - { - ++mMouseOverCounter; + if(mMouseInMenu) + onMouseInMenu_callback(true); +} - } else if(mMouseOverCounter == mMouseHoverAmount) - { - ++mMouseOverCounter; - onMouseInMenu_callback(true); // Last parameter indicates if we've entered or left the menu - } +void GuiMenuBar::insert(SimObject* pObject, S32 pos) +{ + PopupMenu* menu = dynamic_cast(pObject); + if (menu == nullptr) + return; + + MenuEntry newMenu; + newMenu.pos = pos >= mMenuList.size() || pos == -1 ? pos = mMenuList.size() : pos; + newMenu.drawBitmapOnly = false; + newMenu.drawBorder = true; + newMenu.bitmapIndex = -1; + newMenu.text = menu->barTitle; + newMenu.visible = true; + newMenu.popupMenu = menu; + + if (pos >= mMenuList.size() || pos == -1) + mMenuList.push_back(newMenu); + else + mMenuList.insert(pos, newMenu); +} + +PopupMenu* GuiMenuBar::getMenu(U32 index) +{ + if (index >= mMenuList.size()) + return nullptr; + + return mMenuList[index].popupMenu; +} + +PopupMenu* GuiMenuBar::findMenu(StringTableEntry barTitle) +{ + for (U32 i = 0; i < mMenuList.size(); i++) + { + if (mMenuList[i].text == barTitle) + return mMenuList[i].popupMenu; + } + + return nullptr; +} + +//----------------------------------------------------------------------------- +// Console Methods +//----------------------------------------------------------------------------- +DefineConsoleMethod(GuiMenuBar, attachToCanvas, void, (const char *canvas, S32 pos), , "(GuiCanvas, pos)") +{ + GuiCanvas* canv = dynamic_cast(Sim::findObject(canvas)); + if (canv) + { + canv->setMenuBar(object); } } + +DefineConsoleMethod(GuiMenuBar, removeFromCanvas, void, (), , "()") +{ + GuiCanvas* canvas = object->getRoot(); + + if(canvas) + canvas->setMenuBar(nullptr); +} + +DefineConsoleMethod(GuiMenuBar, getMenuCount, S32, (), , "()") +{ + return object->getMenuListCount(); +} + +DefineConsoleMethod(GuiMenuBar, getMenu, S32, (S32 index), (0), "(Index)") +{ + return object->getMenu(index)->getId(); +} + +//----------------------------------------------------------------------------- +DefineConsoleMethod(GuiMenuBar, insert, void, (SimObject* pObject, S32 pos), (nullAsType(), -1), "(object, pos) insert object at position") +{ + object->insert(pObject, pos); +} + +DefineConsoleMethod(GuiMenuBar, findMenu, S32, (const char* barTitle), (""), "(barTitle)") +{ + StringTableEntry barTitleStr = StringTable->insert(barTitle); + PopupMenu* menu = object->findMenu(barTitleStr); + + if (menu) + return menu->getId(); + else + return 0; +} diff --git a/Engine/source/gui/editor/guiMenuBar.h b/Engine/source/gui/editor/guiMenuBar.h index a41455a16..054be37cc 100644 --- a/Engine/source/gui/editor/guiMenuBar.h +++ b/Engine/source/gui/editor/guiMenuBar.h @@ -23,119 +23,43 @@ #ifndef _GUIMENUBAR_H_ #define _GUIMENUBAR_H_ -#ifndef _GUITEXTLISTCTRL_H_ -#include "gui/controls/guiTextListCtrl.h" -#endif #ifndef _GUITICKCTRL_H_ #include "gui/shiny/guiTickCtrl.h" #endif +#ifndef _POPUPMENU_H_ +#include "gui/editor/popupMenu.h" +#endif + class GuiMenuBar; -class GuiMenuTextListCtrl; class WindowInputGenerator; -class GuiMenuBackgroundCtrl : public GuiControl -{ - typedef GuiControl Parent; - -protected: - GuiMenuBar *mMenuBarCtrl; - GuiMenuTextListCtrl *mTextList; -public: - GuiMenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl* textList); - void onMouseDown(const GuiEvent &event); - void onMouseMove(const GuiEvent &event); - void onMouseDragged(const GuiEvent &event); -}; - -class GuiSubmenuBackgroundCtrl : public GuiMenuBackgroundCtrl -{ - typedef GuiMenuBackgroundCtrl Parent; - -public: - GuiSubmenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl* textList); - bool pointInControl(const Point2I & parentCoordPoint); - void onMouseDown(const GuiEvent &event); -}; - //------------------------------------------------------------------------------ - -class GuiMenuTextListCtrl : public GuiTextListCtrl -{ - private: - typedef GuiTextListCtrl Parent; - - protected: - GuiMenuBar *mMenuBarCtrl; - - public: - bool isSubMenu; // Indicates that this text list is in a submenu - - GuiMenuTextListCtrl(); // for inheritance - GuiMenuTextListCtrl(GuiMenuBar *ctrl); - - // GuiControl overloads: - bool onKeyDown(const GuiEvent &event); - void onMouseDown(const GuiEvent &event); - void onMouseUp(const GuiEvent &event); - void onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver); - - virtual void onCellHighlighted(Point2I cell); // Added -}; - -//------------------------------------------------------------------------------ - class GuiMenuBar : public GuiTickCtrl // Was: GuiControl { typedef GuiTickCtrl Parent; // Was: GuiControl Parent; public: - struct Menu; + struct MenuEntry + { + U32 pos; + RectI bounds; - struct MenuItem // an individual item in a pull-down menu - { - char *text; // the text of the menu item - U32 id; // a script-assigned identifier - char *accelerator; // the keyboard accelerator shortcut for the menu item - U32 acceleratorIndex; // index of this accelerator - bool enabled; // true if the menu item is selectable - bool visible; // true if the menu item is visible - S32 bitmapIndex; // index of the bitmap in the bitmap array - S32 checkGroup; // the group index of the item visa vi check marks - - // only one item in the group can be checked. - MenuItem *nextMenuItem; // next menu item in the linked list - - bool isSubmenu; // This menu item has a submenu that will be displayed - - Menu* submenuParentMenu; // For a submenu, this is the parent menu - Menu* submenu; - String cmd; - }; - - struct Menu - { - char *text; - U32 id; - RectI bounds; bool visible; - S32 bitmapIndex; // Index of the bitmap in the bitmap array (-1 = no bitmap) - bool drawBitmapOnly; // Draw only the bitmap and not the text - bool drawBorder; // Should a border be drawn around this menu (usually if we only have a bitmap, we don't want a border) + S32 bitmapIndex; + bool drawBitmapOnly; - Menu *nextMenu; - MenuItem *firstMenuItem; - }; - - GuiMenuBackgroundCtrl *mBackground; - GuiMenuTextListCtrl *mTextList; - - GuiSubmenuBackgroundCtrl *mSubmenuBackground; // Background for a submenu - GuiMenuTextListCtrl *mSubmenuTextList; // Text list for a submenu + bool drawBorder; - Vector mMenuList; - Menu *mouseDownMenu; - Menu *mouseOverMenu; + StringTableEntry text; + PopupMenu* popupMenu; + }; + + Vector mMenuList; + + MenuEntry *mouseDownMenu; + MenuEntry *mouseOverMenu; MenuItem* mouseDownSubmenu; // Stores the menu item that is a submenu that has been selected MenuItem* mouseOverSubmenu; // Stores the menu item that is a submenu that has been highlighted @@ -151,59 +75,26 @@ public: S32 mVerticalMargin; // Top and bottom margin around the text of each menu S32 mBitmapMargin; // Margin between a menu's bitmap and text - // Used to keep track of the amount of ticks that the mouse is hovering - // over a menu. - S32 mMouseOverCounter; - bool mCountMouseOver; - S32 mMouseHoverAmount; + U32 mMenubarHeight; + + bool mMouseInMenu; GuiMenuBar(); + + void onRemove(); bool onWake(); void onSleep(); - // internal menu handling functions - // these are used by the script manipulation functions to add/remove/change menu items - static Menu* sCreateMenu(const char *menuText, U32 menuId); - void addMenu(Menu *menu, S32 pos = -1); - void addMenu(const char *menuText, U32 menuId); - Menu *findMenu(const char *menu); // takes either a menu text or a string id - static MenuItem *findMenuItem(Menu *menu, const char *menuItem); // takes either a menu text or a string id - void removeMenu(Menu *menu); - static void removeMenuItem(Menu *menu, MenuItem *menuItem); - static MenuItem* addMenuItem(Menu *menu, const char *text, U32 id, const char *accelerator, S32 checkGroup, const char *cmd); - static MenuItem* addMenuItem(Menu *menu, MenuItem *menuItem); - static void clearMenuItems(Menu *menu); - void clearMenus(); + virtual void addObject(SimObject* object); - void attachToMenuBar(Menu* menu, S32 pos = -1); - void removeFromMenuBar(Menu* menu); - - // Methods to deal with submenus - static MenuItem* findSubmenuItem(Menu *menu, const char *menuItem, const char *submenuItem); - static MenuItem* findSubmenuItem(MenuItem *menuItem, const char *submenuItem); - static void addSubmenuItem(Menu *menu, MenuItem *submenu, const char *text, U32 id, const char *accelerator, S32 checkGroup); - static void addSubmenuItem(Menu *menu, MenuItem *submenu, MenuItem *newMenuItem ); - static void removeSubmenuItem(MenuItem *menuItem, MenuItem *submenuItem); - static void clearSubmenuItems(MenuItem *menuitem); - void onSubmenuAction(S32 selectionIndex, const RectI& bounds, Point2I cellSize); - void closeSubmenu(); - void checkSubmenuMouseMove(const GuiEvent &event); - MenuItem *findHitMenuItem(Point2I mousePoint); - - void highlightedMenuItem(S32 selectionIndex, const RectI& bounds, Point2I cellSize); // Called whenever a menu item is highlighted by the mouse - - // display/mouse functions - - Menu *findHitMenu(Point2I mousePoint); - - // Called when the GUI theme changes and a bitmap arrary may need updating - // void onThemeChange(); + MenuEntry *findHitMenu(Point2I mousePoint); void onPreRender(); void onRender(Point2I offset, const RectI &updateRect); void checkMenuMouseMove(const GuiEvent &event); void onMouseMove(const GuiEvent &event); + void onMouseEnter(const GuiEvent &event); void onMouseLeave(const GuiEvent &event); void onMouseDown(const GuiEvent &event); void onMouseDragged(const GuiEvent &event); @@ -215,18 +106,22 @@ public: void removeWindowAcceleratorMap( WindowInputGenerator &inputGenerator ); void acceleratorKeyPress(U32 index); - virtual void menuItemSelected(Menu *menu, MenuItem *item); - // Added to support 'ticks' void processTick(); + void insert(SimObject* pObject, S32 pos); + static void initPersistFields(); + U32 getMenuListCount() { return mMenuList.size(); } + + PopupMenu* getMenu(U32 index); + PopupMenu* findMenu(StringTableEntry barTitle); + DECLARE_CONOBJECT(GuiMenuBar); DECLARE_CALLBACK( void, onMouseInMenu, ( bool hasLeftMenu )); DECLARE_CALLBACK( void, onMenuSelect, ( S32 menuId, const char* menuText )); DECLARE_CALLBACK( void, onMenuItemSelect, ( S32 menuId, const char* menuText, S32 menuItemId, const char* menuItemText )); - DECLARE_CALLBACK( void, onSubmenuSelect, ( S32 submenuId, const char* submenuText )); }; #endif diff --git a/Engine/source/gui/editor/guiPopupMenuCtrl.cpp b/Engine/source/gui/editor/guiPopupMenuCtrl.cpp index 36e693203..d03a8bec1 100644 --- a/Engine/source/gui/editor/guiPopupMenuCtrl.cpp +++ b/Engine/source/gui/editor/guiPopupMenuCtrl.cpp @@ -25,20 +25,32 @@ #include "gfx/primBuilder.h" #include "gui/core/guiCanvas.h" -GuiPopupMenuBackgroundCtrl::GuiPopupMenuBackgroundCtrl(GuiPopupMenuTextListCtrl *textList) +GuiPopupMenuBackgroundCtrl::GuiPopupMenuBackgroundCtrl() { - mTextList = textList; - mTextList->mBackground = this; + mMenuBarCtrl = nullptr; } void GuiPopupMenuBackgroundCtrl::onMouseDown(const GuiEvent &event) { - mTextList->setSelectedCell(Point2I(-1, -1)); + +} + +void GuiPopupMenuBackgroundCtrl::onMouseUp(const GuiEvent &event) +{ + clearPopups(); + + //Pass along the event just in case we clicked over a menu item. We don't want to eat the input for it. + if (mMenuBarCtrl) + mMenuBarCtrl->onMouseUp(event); + close(); } void GuiPopupMenuBackgroundCtrl::onMouseMove(const GuiEvent &event) { + //It's possible we're trying to pan through a menubar while a popup is displayed. Pass along our event to the menubar for good measure + if (mMenuBarCtrl) + mMenuBarCtrl->onMouseMove(event); } void GuiPopupMenuBackgroundCtrl::onMouseDragged(const GuiEvent &event) @@ -47,27 +59,66 @@ void GuiPopupMenuBackgroundCtrl::onMouseDragged(const GuiEvent &event) void GuiPopupMenuBackgroundCtrl::close() { - getRoot()->removeObject(this); + if(getRoot()) + getRoot()->removeObject(this); + + mMenuBarCtrl = nullptr; +} + +S32 GuiPopupMenuBackgroundCtrl::findPopupMenu(PopupMenu* menu) +{ + S32 menuId = -1; + + for (U32 i = 0; i < mPopups.size(); i++) + { + if (mPopups[i]->getId() == menu->getId()) + return i; + } + + return menuId; +} + +void GuiPopupMenuBackgroundCtrl::clearPopups() +{ + for (U32 i = 0; i < mPopups.size(); i++) + { + mPopups[i]->mTextList->setSelectedCell(Point2I(-1, -1)); + mPopups[i]->mTextList->mPopup->hidePopup(); + } } GuiPopupMenuTextListCtrl::GuiPopupMenuTextListCtrl() { isSubMenu = false; // Added - mMenu = NULL; - mMenuBar = NULL; - mPopup = NULL; + + mMenuBar = nullptr; + mPopup = nullptr; + + mLastHighlightedMenuIdx = -1; } void GuiPopupMenuTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver) { - if (dStrcmp(mList[cell.y].text + 3, "-\t")) // Was: dStrcmp(mList[cell.y].text + 2, "-\t")) but has been changed to take into account the submenu flag - Parent::onRenderCell(offset, cell, selected, mouseOver); - else + //check if we're a real entry, or if it's a divider + if (mPopup->mMenuItems[cell.y].isSpacer) { S32 yp = offset.y + mCellSize.y / 2; - GFX->getDrawUtil()->drawLine(offset.x, yp, offset.x + mCellSize.x, yp, ColorI(128, 128, 128)); - GFX->getDrawUtil()->drawLine(offset.x, yp + 1, offset.x + mCellSize.x, yp + 1, ColorI(255, 255, 255)); + GFX->getDrawUtil()->drawLine(offset.x + 5, yp, offset.x + mCellSize.x - 5, yp, ColorI(128, 128, 128)); } + else + { + if (dStrcmp(mList[cell.y].text + 3, "-\t")) // Was: dStrcmp(mList[cell.y].text + 2, "-\t")) but has been changed to take into account the submenu flag + { + Parent::onRenderCell(offset, cell, selected, mouseOver); + } + else + { + S32 yp = offset.y + mCellSize.y / 2; + GFX->getDrawUtil()->drawLine(offset.x, yp, offset.x + mCellSize.x, yp, ColorI(128, 128, 128)); + GFX->getDrawUtil()->drawLine(offset.x, yp + 1, offset.x + mCellSize.x, yp + 1, ColorI(255, 255, 255)); + } + } + // now see if there's a bitmap... U8 idx = mList[cell.y].text[0]; if (idx != 1) @@ -101,16 +152,22 @@ void GuiPopupMenuTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool s S32 bottom = top + 8; S32 middle = top + 4; - PrimBuild::begin(GFXTriangleList, 3); - if (selected || mouseOver) - PrimBuild::color(mProfile->mFontColorHL); - else - PrimBuild::color(mProfile->mFontColor); + //PrimBuild::begin(GFXTriangleList, 3); - PrimBuild::vertex2i(left, top); + ColorI color = ColorI::BLACK; + if (selected || mouseOver) + color = mProfile->mFontColorHL; + else + color = mProfile->mFontColor; + + GFX->getDrawUtil()->drawLine(Point2I(left, top), Point2I(right, middle), color); + GFX->getDrawUtil()->drawLine(Point2I(right, middle), Point2I(left, bottom), color); + GFX->getDrawUtil()->drawLine(Point2I(left, bottom), Point2I(left, top), color); + + /*PrimBuild::vertex2i(left, top); PrimBuild::vertex2i(right, middle); PrimBuild::vertex2i(left, bottom); - PrimBuild::end(); + PrimBuild::end();*/ } } @@ -153,17 +210,12 @@ void GuiPopupMenuTextListCtrl::onMouseUp(const GuiEvent &event) if (selectionIndex != -1) { - GuiMenuBar::MenuItem *list = mMenu->firstMenuItem; + MenuItem *item = &mPopup->mMenuItems[selectionIndex]; - while (selectionIndex && list) + if (item) { - list = list->nextMenuItem; - selectionIndex--; - } - if (list) - { - if (list->enabled) - dAtob(Con::executef(mPopup, "onSelectItem", Con::getIntArg(getSelectedCell().y), list->text ? list->text : "")); + if (item->enabled) + dAtob(Con::executef(mPopup, "onSelectItem", Con::getIntArg(getSelectedCell().y), item->text.isNotEmpty() ? item->text : "")); } } @@ -181,4 +233,23 @@ void GuiPopupMenuTextListCtrl::onCellHighlighted(Point2I cell) Point2I globalpoint = localToGlobalCoord(globalbounds.point); globalbounds.point = globalpoint; } + + S32 selectionIndex = cell.y; + + if (selectionIndex != -1 && mLastHighlightedMenuIdx != selectionIndex) + { + mLastHighlightedMenuIdx = selectionIndex; + + mPopup->hidePopupSubmenus(); + } + + if (selectionIndex != -1) + { + MenuItem *list = &mPopup->mMenuItems[selectionIndex]; + + if (list->isSubmenu && list->subMenu != nullptr) + { + list->subMenu->showPopup(getRoot(), getPosition().x + mCellSize.x, getPosition().y + (selectionIndex * mCellSize.y)); + } + } } \ No newline at end of file diff --git a/Engine/source/gui/editor/guiPopupMenuCtrl.h b/Engine/source/gui/editor/guiPopupMenuCtrl.h index c26fa855d..54632a009 100644 --- a/Engine/source/gui/editor/guiPopupMenuCtrl.h +++ b/Engine/source/gui/editor/guiPopupMenuCtrl.h @@ -42,6 +42,7 @@ class GuiPopupMenuBackgroundCtrl; class GuiPopupMenuTextListCtrl : public GuiTextListCtrl { friend class GuiPopupMenuBackgroundCtrl; + friend class PopupMenu; private: typedef GuiTextListCtrl Parent; @@ -51,10 +52,12 @@ private: public: bool isSubMenu; // Indicates that this text list is in a submenu Point2I maxBitmapSize; - GuiMenuBar::Menu* mMenu; + GuiMenuBar* mMenuBar; PopupMenu* mPopup; + S32 mLastHighlightedMenuIdx; + GuiPopupMenuTextListCtrl(); // GuiControl overloads: @@ -70,16 +73,21 @@ class GuiPopupMenuBackgroundCtrl : public GuiControl { typedef GuiControl Parent; -protected: - GuiPopupMenuTextListCtrl *mTextList; - public: - GuiPopupMenuBackgroundCtrl(GuiPopupMenuTextListCtrl* textList); + GuiPopupMenuBackgroundCtrl(); void onMouseDown(const GuiEvent &event); + void onMouseUp(const GuiEvent &event); void onMouseMove(const GuiEvent &event); void onMouseDragged(const GuiEvent &event); void close(); + + void clearPopups(); + + S32 findPopupMenu(PopupMenu* menu); + + Vector mPopups; + GuiMenuBar* mMenuBarCtrl; }; #endif \ No newline at end of file diff --git a/Engine/source/gui/editor/guiShapeEdPreview.cpp b/Engine/source/gui/editor/guiShapeEdPreview.cpp index 481544851..f04ef371a 100644 --- a/Engine/source/gui/editor/guiShapeEdPreview.cpp +++ b/Engine/source/gui/editor/guiShapeEdPreview.cpp @@ -926,8 +926,8 @@ void GuiShapeEdPreview::handleMouseDown(const GuiEvent& event, GizmoMode mode) } } - if ( mode == RotateMode ) - mRenderCameraAxes = true; + //if ( mode == RotateMode ) + // mRenderCameraAxes = true; } void GuiShapeEdPreview::handleMouseUp(const GuiEvent& event, GizmoMode mode) @@ -941,8 +941,8 @@ void GuiShapeEdPreview::handleMouseUp(const GuiEvent& event, GizmoMode mode) mGizmo->on3DMouseUp( mLastEvent ); } - if ( mode == RotateMode ) - mRenderCameraAxes = false; + //if ( mode == RotateMode ) + // mRenderCameraAxes = false; } void GuiShapeEdPreview::handleMouseMove(const GuiEvent& event, GizmoMode mode) @@ -1164,6 +1164,19 @@ void GuiShapeEdPreview::computeSceneBounds(Box3F& bounds) { if ( mModel ) mModel->computeBounds( mCurrentDL, bounds ); + + if (bounds.getExtents().x < POINT_EPSILON || bounds.getExtents().y < POINT_EPSILON || bounds.getExtents().z < POINT_EPSILON) + { + bounds.set(Point3F::Zero); + + //We probably don't have any actual meshes in this model, so compute using the bones if we have them + for (S32 i = 0; i < mModel->getShape()->nodes.size(); i++) + { + Point3F nodePos = mModel->mNodeTransforms[i].getPosition(); + + bounds.extend(nodePos); + } + } } void GuiShapeEdPreview::updateDetailLevel(const SceneRenderState* state) diff --git a/Engine/source/gui/editor/inspector/entityGroup.cpp b/Engine/source/gui/editor/inspector/entityGroup.cpp index c833d336d..7b7559833 100644 --- a/Engine/source/gui/editor/inspector/entityGroup.cpp +++ b/Engine/source/gui/editor/inspector/entityGroup.cpp @@ -70,7 +70,8 @@ bool GuiInspectorEntityGroup::inspectGroup() { Entity* target = dynamic_cast(mParent->getInspectObject(0)); - Con::executef(this, "inspectObject", target->getIdString()); + if(target) + Con::executef(this, "inspectObject", target->getIdString()); } return true; diff --git a/Engine/source/gui/editor/inspector/variableField.h b/Engine/source/gui/editor/inspector/variableField.h index 39ba2e2b8..8bb382a58 100644 --- a/Engine/source/gui/editor/inspector/variableField.h +++ b/Engine/source/gui/editor/inspector/variableField.h @@ -57,6 +57,7 @@ public: protected: StringTableEntry mVariableName; + StringTableEntry mSetCallbackName; SimObject* mOwnerObject; }; diff --git a/Engine/source/gui/editor/inspector/variableGroup.cpp b/Engine/source/gui/editor/inspector/variableGroup.cpp index 2d03f7483..83e4f3c32 100644 --- a/Engine/source/gui/editor/inspector/variableGroup.cpp +++ b/Engine/source/gui/editor/inspector/variableGroup.cpp @@ -151,6 +151,9 @@ bool GuiInspectorVariableGroup::inspectGroup() fieldGui->setInspectorField(NULL, mFields[i]->mFieldLabel); fieldGui->setDocs(mFields[i]->mFieldDescription); + if(mFields[i]->mSetCallbackName != StringTable->EmptyString()) + fieldGui->setSpecialEditCallbackName(mFields[i]->mSetCallbackName); + /*if (mFields[i]->mSetCallbackName != StringTable->EmptyString()) { fieldGui->on.notify() diff --git a/Engine/source/gui/editor/inspector/variableInspector.cpp b/Engine/source/gui/editor/inspector/variableInspector.cpp index 6e673bc34..115e48b83 100644 --- a/Engine/source/gui/editor/inspector/variableInspector.cpp +++ b/Engine/source/gui/editor/inspector/variableInspector.cpp @@ -167,6 +167,10 @@ void GuiVariableInspector::addField(const char* name, const char* label, const c fieldTypeMask = TypeColorF; else if (newField.mFieldTypeName == StringTable->insert("ease")) fieldTypeMask = TypeEaseF; + else if (newField.mFieldTypeName == StringTable->insert("command")) + fieldTypeMask = TypeCommand; + else if (newField.mFieldTypeName == StringTable->insert("filename")) + fieldTypeMask = TypeStringFilename; else fieldTypeMask = -1; @@ -191,7 +195,10 @@ void GuiVariableInspector::addCallbackField(const char* name, const char* label, void GuiVariableInspector::clearFields() { + mGroups.clear(); mFields.clear(); + clear(); + update(); } diff --git a/Engine/source/gui/editor/popupMenu.cpp b/Engine/source/gui/editor/popupMenu.cpp new file mode 100644 index 000000000..0e5db18da --- /dev/null +++ b/Engine/source/gui/editor/popupMenu.cpp @@ -0,0 +1,506 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "gui/editor/popupMenu.h" +#include "console/consoleTypes.h" +#include "console/engineAPI.h" +#include "gui/core/guiCanvas.h" +#include "core/util/safeDelete.h" +#include "gui/editor/guiPopupMenuCtrl.h" +#include "gui/editor/guiMenuBar.h" + +static U32 sMaxPopupGUID = 0; +PopupMenuEvent PopupMenu::smPopupMenuEvent; +bool PopupMenu::smSelectionEventHandled = false; + +/// Event class used to remove popup menus from the event notification in a safe way +class PopUpNotifyRemoveEvent : public SimEvent +{ +public: + void process(SimObject *object) + { + PopupMenu::smPopupMenuEvent.remove((PopupMenu *)object, &PopupMenu::handleSelectEvent); + } +}; + +//----------------------------------------------------------------------------- +// Constructor/Destructor +//----------------------------------------------------------------------------- +PopupMenu::PopupMenu() +{ + bitmapIndex = -1; + + barTitle = StringTable->EmptyString(); + + mMenuBarCtrl = nullptr; + mTextList = nullptr; + + isSubmenu = false; +} + +PopupMenu::~PopupMenu() +{ + PopupMenu::smPopupMenuEvent.remove(this, &PopupMenu::handleSelectEvent); +} + +IMPLEMENT_CONOBJECT(PopupMenu); + +ConsoleDocClass( PopupMenu, + "@brief PopupMenu represents a system menu.\n\n" + "You can add menu items to the menu, but there is no torque object associated " + "with these menu items, they exist only in a platform specific manner.\n\n" + "@note Internal use only\n\n" + "@internal" +); + +//----------------------------------------------------------------------------- +void PopupMenu::initPersistFields() +{ + Parent::initPersistFields(); + + addField("barTitle", TypeCaseString, Offset(barTitle, PopupMenu), ""); +} + +//----------------------------------------------------------------------------- +bool PopupMenu::onAdd() +{ + if(! Parent::onAdd()) + return false; + + Con::executef(this, "onAdd"); + return true; +} + +void PopupMenu::onRemove() +{ + Con::executef(this, "onRemove"); + + Parent::onRemove(); +} + +//----------------------------------------------------------------------------- +void PopupMenu::onMenuSelect() +{ + Con::executef(this, "onMenuSelect"); +} + +//----------------------------------------------------------------------------- +void PopupMenu::handleSelectEvent(U32 popID, U32 command) +{ +} + +//----------------------------------------------------------------------------- +bool PopupMenu::onMessageReceived(StringTableEntry queue, const char* event, const char* data) +{ + return Con::executef(this, "onMessageReceived", queue, event, data); +} + +bool PopupMenu::onMessageObjectReceived(StringTableEntry queue, Message *msg ) +{ + return Con::executef(this, "onMessageReceived", queue, Con::getIntArg(msg->getId())); +} + +////////////////////////////////////////////////////////////////////////// +// Platform Menu Data +////////////////////////////////////////////////////////////////////////// +GuiMenuBar* PopupMenu::getMenuBarCtrl() +{ + return mMenuBarCtrl; +} + +////////////////////////////////////////////////////////////////////////// +// Public Methods +////////////////////////////////////////////////////////////////////////// +S32 PopupMenu::insertItem(S32 pos, const char *title, const char* accelerator, const char* cmd) +{ + String titleString = title; + + MenuItem newItem; + newItem.id = pos; + newItem.text = titleString; + newItem.cmd = cmd; + + if (titleString.isEmpty() || titleString == String("-")) + newItem.isSpacer = true; + else + newItem.isSpacer = false; + + if (accelerator[0]) + newItem.accelerator = dStrdup(accelerator); + else + newItem.accelerator = NULL; + + newItem.visible = true; + newItem.isChecked = false; + newItem.acceleratorIndex = 0; + newItem.enabled = !newItem.isSpacer; + + newItem.isSubmenu = false; + newItem.subMenu = nullptr; + newItem.subMenuParentMenu = nullptr; + + mMenuItems.push_back(newItem); + + return pos; +} + +S32 PopupMenu::insertSubMenu(S32 pos, const char *title, PopupMenu *submenu) +{ + S32 itemPos = insertItem(pos, title, "", ""); + + mMenuItems[itemPos].isSubmenu = true; + mMenuItems[itemPos].subMenu = submenu; + mMenuItems[itemPos].subMenuParentMenu = this; + + submenu->isSubmenu = true; + + return itemPos; +} + +bool PopupMenu::setItem(S32 pos, const char *title, const char* accelerator, const char* cmd) +{ + String titleString = title; + + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (mMenuItems[i].text == titleString) + { + mMenuItems[i].id = pos; + mMenuItems[i].cmd = cmd; + + if (accelerator && accelerator[0]) + mMenuItems[i].accelerator = dStrdup(accelerator); + else + mMenuItems[i].accelerator = NULL; + return true; + } + } + + return false; +} + +void PopupMenu::removeItem(S32 itemPos) +{ + if (mMenuItems.size() < itemPos || itemPos < 0) + return; + + mMenuItems.erase(itemPos); +} + +////////////////////////////////////////////////////////////////////////// +void PopupMenu::enableItem(S32 pos, bool enable) +{ + if (mMenuItems.size() < pos || pos < 0) + return; + + mMenuItems[pos].enabled = enable; +} + +void PopupMenu::checkItem(S32 pos, bool checked) +{ + if (mMenuItems.size() < pos || pos < 0) + return; + + if (checked && mMenuItems[pos].checkGroup != -1) + { + // first, uncheck everything in the group: + for (U32 i = 0; i < mMenuItems.size(); i++) + if (mMenuItems[i].checkGroup == mMenuItems[pos].checkGroup && mMenuItems[i].isChecked) + mMenuItems[i].isChecked = false; + } + + mMenuItems[pos].isChecked; +} + +void PopupMenu::checkRadioItem(S32 firstPos, S32 lastPos, S32 checkPos) +{ + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (mMenuItems[i].id >= firstPos && mMenuItems[i].id <= lastPos) + { + mMenuItems[i].isChecked = false; + } + } +} + +bool PopupMenu::isItemChecked(S32 pos) +{ + if (mMenuItems.size() < pos || pos < 0) + return false; + + return mMenuItems[pos].isChecked; +} + +U32 PopupMenu::getItemCount() +{ + return mMenuItems.size(); +} + +////////////////////////////////////////////////////////////////////////// +bool PopupMenu::canHandleID(U32 id) +{ + return true; +} + +bool PopupMenu::handleSelect(U32 command, const char *text /* = NULL */) +{ + return dAtob(Con::executef(this, "onSelectItem", Con::getIntArg(command), text ? text : "")); +} + +////////////////////////////////////////////////////////////////////////// +void PopupMenu::showPopup(GuiCanvas *owner, S32 x /* = -1 */, S32 y /* = -1 */) +{ + if (owner == NULL) + return; + + GuiControl* editorGui; + Sim::findObject("EditorGui", editorGui); + + if (editorGui) + { + GuiPopupMenuBackgroundCtrl* backgroundCtrl; + Sim::findObject("PopUpMenuControl", backgroundCtrl); + + GuiControlProfile* profile; + Sim::findObject("GuiMenubarProfile", profile); + + if (!profile) + return; + + if (mTextList == nullptr) + { + mTextList = new GuiPopupMenuTextListCtrl(); + mTextList->registerObject(); + mTextList->setControlProfile(profile); + + mTextList->mPopup = this; + mTextList->mMenuBar = getMenuBarCtrl(); + } + + if (!backgroundCtrl) + { + backgroundCtrl = new GuiPopupMenuBackgroundCtrl(); + + backgroundCtrl->registerObject("PopUpMenuControl"); + } + + if (!backgroundCtrl || !mTextList) + return; + + if (!isSubmenu) + { + //if we're a 'parent' menu, then tell the background to clear out all existing other popups + + backgroundCtrl->clearPopups(); + } + + //find out if we're doing a first-time add + S32 popupIndex = backgroundCtrl->findPopupMenu(this); + + if (popupIndex == -1) + { + backgroundCtrl->addObject(mTextList); + backgroundCtrl->mPopups.push_back(this); + } + + mTextList->mBackground = backgroundCtrl; + + owner->pushDialogControl(backgroundCtrl, 10); + + //Set the background control's menubar, if any, and if it's not already set + if(backgroundCtrl->mMenuBarCtrl == nullptr) + backgroundCtrl->mMenuBarCtrl = getMenuBarCtrl(); + + backgroundCtrl->setExtent(editorGui->getExtent()); + + mTextList->clear(); + + S32 textWidth = 0, width = 0; + S32 acceleratorWidth = 0; + GFont *font = profile->mFont; + + Point2I maxBitmapSize = Point2I(0, 0); + + S32 numBitmaps = profile->mBitmapArrayRects.size(); + if (numBitmaps) + { + RectI *bitmapBounds = profile->mBitmapArrayRects.address(); + for (S32 i = 0; i < numBitmaps; i++) + { + if (bitmapBounds[i].extent.x > maxBitmapSize.x) + maxBitmapSize.x = bitmapBounds[i].extent.x; + if (bitmapBounds[i].extent.y > maxBitmapSize.y) + maxBitmapSize.y = bitmapBounds[i].extent.y; + } + } + + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (!mMenuItems[i].visible) + continue; + + S32 iTextWidth = font->getStrWidth(mMenuItems[i].text.c_str()); + S32 iAcceleratorWidth = mMenuItems[i].accelerator ? font->getStrWidth(mMenuItems[i].accelerator) : 0; + + if (iTextWidth > textWidth) + textWidth = iTextWidth; + if (iAcceleratorWidth > acceleratorWidth) + acceleratorWidth = iAcceleratorWidth; + } + + width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4; + + mTextList->setCellSize(Point2I(width, font->getHeight() + 2)); + mTextList->clearColumnOffsets(); + mTextList->addColumnOffset(-1); // add an empty column in for the bitmap index. + mTextList->addColumnOffset(maxBitmapSize.x + 1); + mTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4); + + U32 entryCount = 0; + + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (!mMenuItems[i].visible) + continue; + + char buf[512]; + + // If this menu item is a submenu, then set the isSubmenu to 2 to indicate + // an arrow should be drawn. Otherwise set the isSubmenu normally. + char isSubmenu = 1; + if (mMenuItems[i].isSubmenu) + isSubmenu = 2; + + char bitmapIndex = 1; + if (mMenuItems[i].bitmapIndex >= 0 && (mMenuItems[i].bitmapIndex * 3 <= profile->mBitmapArrayRects.size())) + bitmapIndex = mMenuItems[i].bitmapIndex + 2; + + dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, mMenuItems[i].text.c_str(), mMenuItems[i].accelerator ? mMenuItems[i].accelerator : ""); + mTextList->addEntry(entryCount, buf); + + if (!mMenuItems[i].enabled) + mTextList->setEntryActive(entryCount, false); + + entryCount++; + } + + Point2I pos = Point2I::Zero; + + if (x == -1 && y == -1) + pos = owner->getCursorPos(); + else + pos = Point2I(x, y); + + mTextList->setPosition(pos); + + //nudge in if we'd overshoot the screen + S32 widthDiff = (mTextList->getPosition().x + mTextList->getExtent().x) - backgroundCtrl->getWidth(); + if (widthDiff > 0) + { + Point2I popupPos = mTextList->getPosition(); + mTextList->setPosition(popupPos.x - widthDiff, popupPos.y); + } + + mTextList->setHidden(false); + } +} + +void PopupMenu::hidePopup() +{ + if (mTextList) + { + mTextList->setHidden(true); + } + + hidePopupSubmenus(); +} + +void PopupMenu::hidePopupSubmenus() +{ + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (mMenuItems[i].subMenu != nullptr) + mMenuItems[i].subMenu->hidePopup(); + } +} + +//----------------------------------------------------------------------------- +// Console Methods +//----------------------------------------------------------------------------- +DefineConsoleMethod(PopupMenu, insertItem, S32, (S32 pos, const char * title, const char * accelerator, const char* cmd), ("", "", ""), "(pos[, title][, accelerator][, cmd])") +{ + return object->insertItem(pos, title, accelerator, cmd); +} + +DefineConsoleMethod(PopupMenu, removeItem, void, (S32 pos), , "(pos)") +{ + object->removeItem(pos); +} + +DefineConsoleMethod(PopupMenu, insertSubMenu, S32, (S32 pos, String title, String subMenu), , "(pos, title, subMenu)") +{ + PopupMenu *mnu = dynamic_cast(Sim::findObject(subMenu)); + if(mnu == NULL) + { + Con::errorf("PopupMenu::insertSubMenu - Invalid PopupMenu object specified for submenu"); + return -1; + } + return object->insertSubMenu(pos, title, mnu); +} + +DefineConsoleMethod(PopupMenu, setItem, bool, (S32 pos, const char * title, const char * accelerator, const char *cmd), (""), "(pos, title[, accelerator][, cmd])") +{ + return object->setItem(pos, title, accelerator, cmd); +} + +//----------------------------------------------------------------------------- + +DefineConsoleMethod(PopupMenu, enableItem, void, (S32 pos, bool enabled), , "(pos, enabled)") +{ + object->enableItem(pos, enabled); +} + +DefineConsoleMethod(PopupMenu, checkItem, void, (S32 pos, bool checked), , "(pos, checked)") +{ + object->checkItem(pos, checked); +} + +DefineConsoleMethod(PopupMenu, checkRadioItem, void, (S32 firstPos, S32 lastPos, S32 checkPos), , "(firstPos, lastPos, checkPos)") +{ + object->checkRadioItem(firstPos, lastPos, checkPos); +} + +DefineConsoleMethod(PopupMenu, isItemChecked, bool, (S32 pos), , "(pos)") +{ + return object->isItemChecked(pos); +} + +DefineConsoleMethod(PopupMenu, getItemCount, S32, (), , "()") +{ + return object->getItemCount(); +} + +//----------------------------------------------------------------------------- +DefineConsoleMethod(PopupMenu, showPopup, void, (const char * canvasName, S32 x, S32 y), ( -1, -1), "(Canvas,[x, y])") +{ + GuiCanvas *pCanvas = dynamic_cast(Sim::findObject(canvasName)); + object->showPopup(pCanvas, x, y); +} diff --git a/Engine/source/platform/menus/popupMenu.h b/Engine/source/gui/editor/popupMenu.h similarity index 69% rename from Engine/source/platform/menus/popupMenu.h rename to Engine/source/gui/editor/popupMenu.h index 8d1239972..9a6dd0821 100644 --- a/Engine/source/platform/menus/popupMenu.h +++ b/Engine/source/gui/editor/popupMenu.h @@ -19,17 +19,43 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#ifndef _POPUPMENU_H_ +#define _POPUPMENU_H_ + #include "console/simBase.h" #include "core/util/tVector.h" #include "util/messaging/dispatcher.h" #include "gui/core/guiCanvas.h" -#ifndef _POPUPMENU_H_ -#define _POPUPMENU_H_ +class PopupMenu; +class GuiMenuBar; +class GuiPopupMenuTextListCtrl; +class GuiPopupMenuBackgroundCtrl; -// Forward ref used by the platform code -struct PlatformPopupMenuData; -class MenuBar; +struct MenuItem // an individual item in a pull-down menu +{ + String text; // the text of the menu item + U32 id; // a script-assigned identifier + char *accelerator; // the keyboard accelerator shortcut for the menu item + U32 acceleratorIndex; // index of this accelerator + bool enabled; // true if the menu item is selectable + bool visible; // true if the menu item is visible + S32 bitmapIndex; // index of the bitmap in the bitmap array + S32 checkGroup; // the group index of the item visa vi check marks - + // only one item in the group can be checked. + + bool isSubmenu; // This menu item has a submenu that will be displayed + + bool isChecked; + + bool isSpacer; + + bool isMenubarEntry; + + PopupMenu* subMenuParentMenu; // For a submenu, this is the parent menu + PopupMenu* subMenu; + String cmd; +}; // PopupMenu represents a menu. // You can add menu items to the menu, but there is no torque object associated @@ -37,30 +63,32 @@ class MenuBar; class PopupMenu : public SimObject, public virtual Dispatcher::IMessageListener { typedef SimObject Parent; - - friend class MenuBar; - -private: - /// Used by MenuBar to attach the menu to the menu bar. Do not use anywhere else. - void attachToMenuBar(GuiCanvas *owner, S32 pos); + friend class GuiMenuBar; + friend class GuiPopupMenuTextListCtrl; + friend class GuiPopupMenuBackgroundCtrl; protected: - PlatformPopupMenuData *mData; - - SimSet *mSubmenus; - SimObjectPtr mCanvas; + Vector mMenuItems; - StringTableEntry mBarTitle; + GuiMenuBar* mMenuBarCtrl; - U32 mPopupGUID; - - bool mIsPopup; + StringTableEntry barTitle; + + RectI bounds; + bool visible; + + S32 bitmapIndex; // Index of the bitmap in the bitmap array (-1 = no bitmap) + bool drawBitmapOnly; // Draw only the bitmap and not the text + bool drawBorder; // Should a border be drawn around this menu (usually if we only have a bitmap, we don't want a border) + + bool isSubmenu; + + //This is the gui control that renders our popup + GuiPopupMenuTextListCtrl *mTextList; public: PopupMenu(); virtual ~PopupMenu(); - void createPlatformPopupMenuData(); - void deletePlatformPopupMenuData(); DECLARE_CONOBJECT(PopupMenu); @@ -72,15 +100,6 @@ public: static PopupMenuEvent smPopupMenuEvent; static bool smSelectionEventHandled; /// Set to true if any menu or submenu handles a selection event - /// Creates the platform specific menu object, a peer to this object. - /// The platform menu *must* exist before calling any method that manipulates - /// menu items or displays the menu. - /// implementd on a per-platform basis. - void createPlatformMenu(); - - void setBarTitle(const char * val) { mBarTitle = StringTable->insert(val, true); } - StringTableEntry getBarTitle() const { return mBarTitle; } - /// pass NULL for @p title to insert a separator /// returns the menu item's ID, or -1 on failure. /// implementd on a per-platform basis. @@ -118,39 +137,7 @@ public: /// Returns the number of items in the menu. U32 getItemCount(); - /// Returns the popup GUID - U32 getPopupGUID() { return mPopupGUID; } - //----------------------------------------------------------------------------- - // New code should not use these methods directly, use the menu bar instead. - // - // They remain for compatibility with old code and will be changing/going away - // once the existing code is moved over to the menu bar. - //----------------------------------------------------------------------------- - - /// Places this menu in the menu bar of the application's main window. - /// @param owner The GuiCanvas that owns the PlatformWindow that this call is associated with - /// @param pos The relative position at which to place the menu. - /// @param title The name of the menu - void attachToMenuBar(GuiCanvas *owner, S32 pos, const char *title); - - /// Removes this menu from the menu bar. - void removeFromMenuBar(); - - //----------------------------------------------------------------------------- - - /// Called when the menu has been attached to the menu bar - void onAttachToMenuBar(GuiCanvas *canvas, S32 pos, const char *title); - - /// Called when the menu has been removed from the menu bar - void onRemoveFromMenuBar(GuiCanvas *canvas); - - /// Returns the position index of this menu on the bar. - S32 getPosOnMenuBar(); - - /// Returns true if this menu is attached to the menu bar - bool isAttachedToMenuBar() { return mCanvas != NULL; } - /// Displays this menu as a popup menu and blocks until the user has selected /// an item. /// @param canvas the owner to show this popup associated with @@ -159,6 +146,9 @@ public: /// implemented on a per-platform basis. void showPopup(GuiCanvas *owner, S32 x = -1, S32 y = -1); + void hidePopup(); + void hidePopupSubmenus(); + /// Returns true iff this menu contains an item that matches @p iD. /// implemented on a per-platform basis. /// TODO: factor out common code @@ -184,6 +174,11 @@ public: virtual bool onMessageReceived(StringTableEntry queue, const char* event, const char* data ); virtual bool onMessageObjectReceived(StringTableEntry queue, Message *msg ); + + bool isVisible() { return visible; } + void setVisible(bool isVis) { visible = isVis; } + + GuiMenuBar* getMenuBarCtrl(); }; #endif // _POPUPMENU_H_ diff --git a/Engine/source/lighting/advanced/advancedLightManager.cpp b/Engine/source/lighting/advanced/advancedLightManager.cpp index 0b14a12a4..3c851cf81 100644 --- a/Engine/source/lighting/advanced/advancedLightManager.cpp +++ b/Engine/source/lighting/advanced/advancedLightManager.cpp @@ -39,6 +39,9 @@ #include "gfx/gfxCardProfile.h" #include "gfx/gfxTextureProfile.h" +#ifndef TORQUE_BASIC_LIGHTING +F32 AdvancedLightManager::smProjectedShadowFilterDistance = 40.0f; +#endif ImplementEnumType( ShadowType, "\n\n" diff --git a/Engine/source/lighting/advanced/advancedLightManager.h b/Engine/source/lighting/advanced/advancedLightManager.h index ac03bad48..ca747d8a0 100644 --- a/Engine/source/lighting/advanced/advancedLightManager.h +++ b/Engine/source/lighting/advanced/advancedLightManager.h @@ -97,6 +97,10 @@ public: LightShadowMap* findShadowMapForObject( SimObject *object ); +#ifndef TORQUE_BASIC_LIGHTING + static F32 getShadowFilterDistance() { return smProjectedShadowFilterDistance; } +#endif + protected: // LightManager @@ -138,6 +142,12 @@ protected: LightingShaderConstants* getLightingShaderConstants(GFXShaderConstBuffer* shader); +#ifndef TORQUE_BASIC_LIGHTING + /// This is used to determine the distance + /// at which the shadow filtering PostEffect + /// will be enabled for ProjectedShadow. + static F32 smProjectedShadowFilterDistance; +#endif }; #endif // _ADVANCEDLIGHTMANAGER_H_ diff --git a/Engine/source/lighting/common/projectedShadow.cpp b/Engine/source/lighting/common/projectedShadow.cpp index 1ad88cd10..2f4657018 100644 --- a/Engine/source/lighting/common/projectedShadow.cpp +++ b/Engine/source/lighting/common/projectedShadow.cpp @@ -43,7 +43,11 @@ #include "materials/materialFeatureTypes.h" #include "console/console.h" #include "postFx/postEffect.h" -#include "lighting/basic/basicLightManager.h" +#ifdef TORQUE_BASIC_LIGHTING +#include "lighting/basic/basicLightManager.h" +#else +#include "lighting/advanced/advancedLightManager.h" +#endif #include "lighting/shadowMap/shadowMatHook.h" #include "materials/materialManager.h" #include "lighting/shadowMap/lightShadowMap.h" @@ -529,8 +533,12 @@ void ProjectedShadow::_renderToTexture( F32 camDist, const TSRenderState &rdata mRenderTarget->resolve(); GFX->popActiveRenderTarget(); - // If we're close enough then filter the shadow. - if ( camDist < BasicLightManager::getShadowFilterDistance() ) + // If we're close enough then filter the shadow. +#ifdef TORQUE_BASIC_LIGHTING + if (camDist < BasicLightManager::getShadowFilterDistance()) +#else + if (camDist < AdvancedLightManager::getShadowFilterDistance()) +#endif { if ( !smShadowFilter ) { diff --git a/Engine/source/lighting/shadowMap/shadowMapManager.cpp b/Engine/source/lighting/shadowMap/shadowMapManager.cpp index 0b58abc37..7b801cc41 100644 --- a/Engine/source/lighting/shadowMap/shadowMapManager.cpp +++ b/Engine/source/lighting/shadowMap/shadowMapManager.cpp @@ -41,6 +41,9 @@ GFX_ImplementTextureProfile(ShadowMapTexProfile, MODULE_BEGIN( ShadowMapManager ) +#ifndef TORQUE_BASIC_LIGHTING + MODULE_SHUTDOWN_AFTER(Scene) +#endif MODULE_INIT { diff --git a/Engine/source/module/moduleDefinition.cpp b/Engine/source/module/moduleDefinition.cpp index 795186aef..c8dae30d8 100644 --- a/Engine/source/module/moduleDefinition.cpp +++ b/Engine/source/module/moduleDefinition.cpp @@ -82,6 +82,8 @@ void ModuleDefinition::initPersistFields() // Call parent. Parent::initPersistFields(); + addProtectedField("ModuleId", TypeString, Offset(mModuleId, ModuleDefinition), &defaultProtectedSetFn, &defaultProtectedGetFn, ""); + /// Module configuration. addProtectedField( "ModuleId", TypeString, Offset(mModuleId, ModuleDefinition), &setModuleId, &defaultProtectedGetFn, "A unique string Id for the module. It can contain any characters except a comma or semi-colon (the asset scope character)." ); addProtectedField( "VersionId", TypeS32, Offset(mVersionId, ModuleDefinition), &setVersionId, &defaultProtectedGetFn, "The version Id. Breaking changes to a module should use a higher version Id." ); diff --git a/Engine/source/module/moduleManager.cpp b/Engine/source/module/moduleManager.cpp index 67a89e3e1..fa53728b7 100644 --- a/Engine/source/module/moduleManager.cpp +++ b/Engine/source/module/moduleManager.cpp @@ -70,7 +70,8 @@ S32 QSORT_CALLBACK moduleDefinitionVersionIdSort( const void* a, const void* b ) ModuleManager::ModuleManager() : mEnforceDependencies(true), mEchoInfo(true), - mDatabaseLocks( 0 ) + mDatabaseLocks( 0 ), + mIgnoreLoadedGroups(false) { // Set module extension. dStrcpy( mModuleExtension, MODULE_MANAGER_MODULE_DEFINITION_EXTENSION ); @@ -1300,6 +1301,106 @@ StringTableEntry ModuleManager::copyModule( ModuleDefinition* pSourceModuleDefin //----------------------------------------------------------------------------- +bool ModuleManager::renameModule(ModuleDefinition* pSourceModuleDefinition, const char* pNewModuleName) +{ + // Sanity! + AssertFatal(pSourceModuleDefinition != NULL, "Cannot copy module using a NULL source module definition."); + AssertFatal(pNewModuleName != NULL, "Cannot rename a module using a NULL module name."); + + // Fetch the source module Id. + StringTableEntry sourceModuleId = pSourceModuleDefinition->getModuleId(); + + // Is the source module definition registered with this module manager? + if (pSourceModuleDefinition->getModuleManager() != this) + { + // No, so warn. + Con::warnf("Module Manager: Cannot rename module Id '%s' as it is not registered with this module manager.", sourceModuleId); + return StringTable->EmptyString(); + } + + TamlModuleIdUpdateVisitor moduleIdUpdateVisitor; + moduleIdUpdateVisitor.setModuleIdFrom(sourceModuleId); + moduleIdUpdateVisitor.setModuleIdTo(pNewModuleName); + + Vector files; + + const char* pExtension = (const char*)"Taml"; + const U32 extensionLength = dStrlen(pExtension); + + Vector directories; + + StringTableEntry modulePath = pSourceModuleDefinition->getModulePath(); + + // Find directories. + if (!Platform::dumpDirectories(modulePath, directories, -1)) + { + // Warn. + Con::warnf("Module Manager: Cannot rename module Id '%s' in directory '%s' as sub-folder scanning/renaming failed.", + sourceModuleId, modulePath); + return false; + } + + // Iterate directories. + for (Vector::iterator basePathItr = directories.begin(); basePathItr != directories.end(); ++basePathItr) + { + // Fetch base path. + StringTableEntry basePath = *basePathItr; + + // Find files. + files.clear(); + if (!Platform::dumpPath(basePath, files, 0)) + { + // Warn. + Con::warnf("Module Manager: Cannot rename module Id '%s' in directory '%s' as sub-folder scanning/renaming failed.", + sourceModuleId, modulePath); + return false; + } + + // Iterate files. + for (Vector::iterator fileItr = files.begin(); fileItr != files.end(); ++fileItr) + { + // Fetch file info. + Platform::FileInfo* pFileInfo = fileItr; + + // Fetch filename. + const char* pFilename = pFileInfo->pFileName; + + // Find filename length. + const U32 filenameLength = dStrlen(pFilename); + + // Skip if extension is longer than filename. + if (extensionLength >= filenameLength) + continue; + + // Skip if extension not found. + if (dStricmp(pFilename + filenameLength - extensionLength, pExtension) != 0) + continue; + + char parseFileBuffer[1024]; + dSprintf(parseFileBuffer, sizeof(parseFileBuffer), "%s/%s", pFileInfo->pFullPath, pFilename); + + // Parse file. + if (!mTaml.parse(parseFileBuffer, moduleIdUpdateVisitor)) + { + // Warn. + Con::warnf("Module Manager: Failed to parse file '%s' whilst renaming module Id '%s' in directory '%s'.", + parseFileBuffer, sourceModuleId, modulePath); + return false; + } + } + } + + // Info. + if (mEchoInfo) + { + Con::printf("Module Manager: Finished renaming module Id '%s' to '%s'.", sourceModuleId, pNewModuleName); + } + + return true; +} + +//----------------------------------------------------------------------------- + bool ModuleManager::synchronizeDependencies( ModuleDefinition* pRootModuleDefinition, const char* pTargetDependencyPath ) { // Sanity! @@ -1986,7 +2087,7 @@ bool ModuleManager::registerModule( const char* pModulePath, const char* pModule } // Is the module group already loaded? - if ( findGroupLoaded( moduleGroup ) != NULL ) + if ( findGroupLoaded( moduleGroup ) != NULL && !mIgnoreLoadedGroups) { // Yes, so warn. Con::warnf( "Module Manager: Found module: '%s' but it is in a module group '%s' which has already been loaded.", diff --git a/Engine/source/module/moduleManager.h b/Engine/source/module/moduleManager.h index 9c7125610..60b81a5f3 100644 --- a/Engine/source/module/moduleManager.h +++ b/Engine/source/module/moduleManager.h @@ -120,6 +120,7 @@ private: char mModuleExtension[256]; Taml mTaml; SimSet mNotificationListeners; + bool mIgnoreLoadedGroups; // Module definition entry. struct ModuleDefinitionEntry : public typeModuleDefinitionVector @@ -161,6 +162,7 @@ public: bool scanModules( const char* pPath, const bool rootOnly = false ); /// Module unregister. + bool registerModule(const char* pModulePath, const char* pModuleFile); bool unregisterModule( const char* pModuleId, const U32 versionId ); /// Module (un)loading. @@ -179,6 +181,9 @@ public: StringTableEntry copyModule( ModuleDefinition* pSourceModuleDefinition, const char* pTargetModuleId, const char* pTargetPath, const bool useVersionPathing ); bool synchronizeDependencies( ModuleDefinition* pRootModuleDefinition, const char* pTargetDependencyPath ); + /// Editing modules + bool renameModule(ModuleDefinition* pSourceModuleDefinition, const char* pNewModuleName); + /// Module updates. inline bool isModuleMergeAvailable( void ) const { return Platform::isFile( getModuleMergeFilePath() ); } bool canMergeModules( const char* pMergeSourcePath ); @@ -188,10 +193,11 @@ public: void addListener( SimObject* pListener ); void removeListener( SimObject* pListener ); + void setIgnoreLoadedGroups(bool doIgnore) { mIgnoreLoadedGroups = doIgnore; } + private: void clearDatabase( void ); bool removeModuleDefinition( ModuleDefinition* pModuleDefinition ); - bool registerModule( const char* pModulePath, const char* pModuleFile ); void raiseModulePreLoadNotifications( ModuleDefinition* pModuleDefinition ); void raiseModulePostLoadNotifications( ModuleDefinition* pModuleDefinition ); diff --git a/Engine/source/module/moduleManager_ScriptBinding.h b/Engine/source/module/moduleManager_ScriptBinding.h index dc560d29a..8abc8aab5 100644 --- a/Engine/source/module/moduleManager_ScriptBinding.h +++ b/Engine/source/module/moduleManager_ScriptBinding.h @@ -46,6 +46,16 @@ DefineEngineMethod(ModuleManager, scanModules, bool, (const char* pRootPath, boo //----------------------------------------------------------------------------- +DefineEngineMethod(ModuleManager, registerModule, bool, (const char* pModulePath, const char* pModuleFile), ("", ""), + "Register the specified module.\n" + "@param moduleId The module Id to register.\n" + "@param versionId The version Id to register.\n" + "@return Whether the module was registered or not.\n") +{ + // Unregister the module. + return object->registerModule(pModulePath, pModuleFile); +} + DefineEngineMethod(ModuleManager, unregisterModule, bool, (const char* pModuleId, bool versionId), ("", false), "Unregister the specified module.\n" "@param moduleId The module Id to unregister.\n" @@ -246,6 +256,30 @@ DefineEngineMethod(ModuleManager, copyModule, String, (const char* sourceModuleD //----------------------------------------------------------------------------- +DefineEngineMethod(ModuleManager, renameModule, bool, (const char* sourceModuleDefinition, const char* pNewModuleName), +("", ""), +"Rename a module.\n" +"@param sourceModuleDefinition The module definition to rename.\n" +"@param pNewModuleName The new name the module should have.\n" +"@return Weither the rename was successful or not.\n") +{ + // Find the source module definition. + ModuleDefinition* pSourceModuleDefinition = dynamic_cast(Sim::findObject(sourceModuleDefinition)); + + // Was the module definition found? + if (pSourceModuleDefinition == NULL) + { + // No, so warn. + Con::warnf("ModuleManager::renameModule() - Could not find source module definition '%s'.", sourceModuleDefinition); + return ""; + } + + // Copy module. + return object->renameModule(pSourceModuleDefinition, pNewModuleName); +} + +//----------------------------------------------------------------------------- + DefineEngineMethod(ModuleManager, synchronizeDependencies, bool, (const char* rootModuleDefinition, const char* pTargetDependencyFolder), ("", ""), "Synchronize the module dependencies of a module definition to a target dependency folder.\n" "@param rootModuleDefinition The module definition used to determine dependencies.\n" @@ -342,3 +376,14 @@ DefineEngineMethod(ModuleManager, removeListener, void, (const char* listenerObj object->removeListener( pListener ); } + +//----------------------------------------------------------------------------- + +DefineEngineMethod(ModuleManager, ignoreLoadedGroups, void, (bool doIgnore), (false), + "Sets if the Module Manager should ingore laoded groups.\n" + "@param doIgnore Whether we should or should not ignore loaded groups.\n" + "@return No return value.\n") +{ + // Check whether the merge modules can current happen or not. + return object->setIgnoreLoadedGroups(doIgnore); +} \ No newline at end of file diff --git a/Engine/source/platform/menus/menuBar.cpp b/Engine/source/platform/menus/menuBar.cpp deleted file mode 100644 index cb70838a8..000000000 --- a/Engine/source/platform/menus/menuBar.cpp +++ /dev/null @@ -1,127 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "platform/menus/menuBar.h" -#include "platform/menus/popupMenu.h" -#include "gui/core/guiCanvas.h" -#include "console/engineAPI.h" - -//----------------------------------------------------------------------------- -// Constructor/Destructor -//----------------------------------------------------------------------------- - -MenuBar::MenuBar() -{ - createPlatformPopupMenuData(); - - mCanvas = NULL; -} - -MenuBar::~MenuBar() -{ - removeFromCanvas(); - - deletePlatformPopupMenuData(); -} - -IMPLEMENT_CONOBJECT(MenuBar); - -ConsoleDocClass( MenuBar, - "@brief Used for rendering platform menu bars\n\n" - "Internal use only\n\n" - "@internal" -); - -//----------------------------------------------------------------------------- -// Public Methods -//----------------------------------------------------------------------------- - -void MenuBar::addObject(SimObject *obj) -{ - Parent::addObject(obj); - updateMenuBar(dynamic_cast(obj)); -} - -void MenuBar::removeObject(SimObject *obj) -{ - Parent::removeObject(obj); - updateMenuBar(dynamic_cast(obj)); -} - -void MenuBar::insertObject(SimObject *obj, S32 pos) -{ - Parent::addObject(obj); - - if(pos >= size()) - pos = size() - 1; - - if(pos < size()) - { - if(pos < 0) pos = 0; - Parent::reOrder(obj, at(pos)); - } - updateMenuBar(dynamic_cast(obj)); -} - -void MenuBar::pushObject(SimObject *obj) -{ - Parent::pushObject(obj); - updateMenuBar(dynamic_cast(obj)); -} - -void MenuBar::popObject() -{ - Parent::popObject(); - updateMenuBar(); -} - -bool MenuBar::reOrder(SimObject *obj, SimObject *target /*= 0*/) -{ - bool ret = Parent::reOrder(obj, target); - if(ret) - updateMenuBar(dynamic_cast(obj)); - return ret; -} - -//----------------------------------------------------------------------------- -// Console Methods -//----------------------------------------------------------------------------- - -DefineConsoleMethod(MenuBar, attachToCanvas, void, (const char *canvas, S32 pos), , "(GuiCanvas, pos)") -{ - object->attachToCanvas(dynamic_cast(Sim::findObject(canvas)), pos); -} - -DefineConsoleMethod(MenuBar, removeFromCanvas, void, (), , "()") -{ - object->removeFromCanvas(); -} - -//----------------------------------------------------------------------------- - -DefineConsoleMethod(MenuBar, insert, void, (SimObject* pObject, S32 pos), ,"(object, pos) insert object at position") -{ - - if(pObject) - object->insertObject(pObject, pos); -} diff --git a/Engine/source/platform/menus/popupMenu.cpp b/Engine/source/platform/menus/popupMenu.cpp deleted file mode 100644 index 7e8aad7ba..000000000 --- a/Engine/source/platform/menus/popupMenu.cpp +++ /dev/null @@ -1,269 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/menus/popupMenu.h" -#include "console/consoleTypes.h" -#include "console/engineAPI.h" -#include "gui/core/guiCanvas.h" -#include "core/util/safeDelete.h" - -static U32 sMaxPopupGUID = 0; -PopupMenuEvent PopupMenu::smPopupMenuEvent; -bool PopupMenu::smSelectionEventHandled = false; - -/// Event class used to remove popup menus from the event notification in a safe way -class PopUpNotifyRemoveEvent : public SimEvent -{ -public: - void process(SimObject *object) - { - PopupMenu::smPopupMenuEvent.remove((PopupMenu *)object, &PopupMenu::handleSelectEvent); - } -}; - -//----------------------------------------------------------------------------- -// Constructor/Destructor -//----------------------------------------------------------------------------- - -PopupMenu::PopupMenu() : mCanvas(NULL) -{ - createPlatformPopupMenuData(); - - mSubmenus = new SimSet; - mSubmenus->registerObject(); - - mBarTitle = StringTable->EmptyString(); - mIsPopup = false; - - mPopupGUID = sMaxPopupGUID++; -} - -PopupMenu::~PopupMenu() -{ - // This searches the menu bar so is safe to call for menus - // that aren't on it, since nothing will happen. - removeFromMenuBar(); - - SimSet::iterator i; - while((i = mSubmenus->begin()) != mSubmenus->end()) - { - (*i)->deleteObject(); - } - - mSubmenus->deleteObject(); - deletePlatformPopupMenuData(); - - PopupMenu::smPopupMenuEvent.remove(this, &PopupMenu::handleSelectEvent); -} - -IMPLEMENT_CONOBJECT(PopupMenu); - -ConsoleDocClass( PopupMenu, - "@brief PopupMenu represents a system menu.\n\n" - "You can add menu items to the menu, but there is no torque object associated " - "with these menu items, they exist only in a platform specific manner.\n\n" - "@note Internal use only\n\n" - "@internal" -); - - -//----------------------------------------------------------------------------- - -void PopupMenu::initPersistFields() -{ - addField("isPopup", TypeBool, Offset(mIsPopup, PopupMenu), "true if this is a pop-up/context menu. defaults to false."); - addField("barTitle", TypeCaseString, Offset(mBarTitle, PopupMenu), "the title of this menu when attached to a menu bar"); - - Parent::initPersistFields(); -} - -//----------------------------------------------------------------------------- - -bool PopupMenu::onAdd() -{ - if(! Parent::onAdd()) - return false; - - createPlatformMenu(); - - Con::executef(this, "onAdd"); - return true; -} - -void PopupMenu::onRemove() -{ - Con::executef(this, "onRemove"); - - Parent::onRemove(); -} - -//----------------------------------------------------------------------------- - -void PopupMenu::onMenuSelect() -{ - Con::executef(this, "onMenuSelect"); -} - -//----------------------------------------------------------------------------- - -void PopupMenu::handleSelectEvent(U32 popID, U32 command) -{ - if (popID == mPopupGUID && canHandleID(command)) - if (handleSelect(command)) - smSelectionEventHandled = true; -} - -//----------------------------------------------------------------------------- - -void PopupMenu::onAttachToMenuBar(GuiCanvas *canvas, S32 pos, const char *title) -{ - mCanvas = canvas; - - // Attached menus must be notified of menu events - smPopupMenuEvent.notify(this, &PopupMenu::handleSelectEvent); - - // Pass on to sub menus - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *mnu = dynamic_cast(*i); - if(mnu == NULL) - continue; - - mnu->onAttachToMenuBar(canvas, pos, title); - } - - // Call script - if(isProperlyAdded()) - Con::executef(this, "onAttachToMenuBar", Con::getIntArg(canvas ? canvas->getId() : 0), Con::getIntArg(pos), title); -} - -void PopupMenu::onRemoveFromMenuBar(GuiCanvas *canvas) -{ - mCanvas = NULL; - - // We are no longer interested in select events, remove ourselves from the notification list in a safe way - Sim::postCurrentEvent(this, new PopUpNotifyRemoveEvent()); - - // Pass on to sub menus - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *mnu = dynamic_cast(*i); - if(mnu == NULL) - continue; - - mnu->onRemoveFromMenuBar(canvas); - } - - // Call script - if(isProperlyAdded()) - Con::executef(this, "onRemoveFromMenuBar", Con::getIntArg(canvas ? canvas->getId() : 0)); -} - -//----------------------------------------------------------------------------- - -bool PopupMenu::onMessageReceived(StringTableEntry queue, const char* event, const char* data) -{ - return Con::executef(this, "onMessageReceived", queue, event, data); -} - - -bool PopupMenu::onMessageObjectReceived(StringTableEntry queue, Message *msg ) -{ - return Con::executef(this, "onMessageReceived", queue, Con::getIntArg(msg->getId())); -} - -//----------------------------------------------------------------------------- -// Console Methods -//----------------------------------------------------------------------------- - -DefineConsoleMethod(PopupMenu, insertItem, S32, (S32 pos, const char * title, const char * accelerator, const char* cmd), ("", "", ""), "(pos[, title][, accelerator][, cmd])") -{ - return object->insertItem(pos, title, accelerator, cmd); -} - -DefineConsoleMethod(PopupMenu, removeItem, void, (S32 pos), , "(pos)") -{ - object->removeItem(pos); -} - -DefineConsoleMethod(PopupMenu, insertSubMenu, S32, (S32 pos, String title, String subMenu), , "(pos, title, subMenu)") -{ - PopupMenu *mnu = dynamic_cast(Sim::findObject(subMenu)); - if(mnu == NULL) - { - Con::errorf("PopupMenu::insertSubMenu - Invalid PopupMenu object specified for submenu"); - return -1; - } - return object->insertSubMenu(pos, title, mnu); -} - -DefineConsoleMethod(PopupMenu, setItem, bool, (S32 pos, const char * title, const char * accelerator, const char *cmd), (""), "(pos, title[, accelerator][, cmd])") -{ - return object->setItem(pos, title, accelerator, cmd); -} - -//----------------------------------------------------------------------------- - -DefineConsoleMethod(PopupMenu, enableItem, void, (S32 pos, bool enabled), , "(pos, enabled)") -{ - object->enableItem(pos, enabled); -} - -DefineConsoleMethod(PopupMenu, checkItem, void, (S32 pos, bool checked), , "(pos, checked)") -{ - object->checkItem(pos, checked); -} - -DefineConsoleMethod(PopupMenu, checkRadioItem, void, (S32 firstPos, S32 lastPos, S32 checkPos), , "(firstPos, lastPos, checkPos)") -{ - object->checkRadioItem(firstPos, lastPos, checkPos); -} - -DefineConsoleMethod(PopupMenu, isItemChecked, bool, (S32 pos), , "(pos)") -{ - return object->isItemChecked(pos); -} - -DefineConsoleMethod(PopupMenu, getItemCount, S32, (), , "()") -{ - return object->getItemCount(); -} - -//----------------------------------------------------------------------------- - -DefineConsoleMethod(PopupMenu, attachToMenuBar, void, (const char * canvasName, S32 pos, const char * title), , "(GuiCanvas, pos, title)") -{ - object->attachToMenuBar(dynamic_cast(Sim::findObject(canvasName)), pos, title); -} - -DefineConsoleMethod(PopupMenu, removeFromMenuBar, void, (), , "()") -{ - object->removeFromMenuBar(); -} - -//----------------------------------------------------------------------------- - -DefineConsoleMethod(PopupMenu, showPopup, void, (const char * canvasName, S32 x, S32 y), ( -1, -1), "(Canvas,[x, y])") -{ - GuiCanvas *pCanvas = dynamic_cast(Sim::findObject(canvasName)); - object->showPopup(pCanvas, x, y); -} diff --git a/Engine/source/platform/nativeDialogs/fileDialog.cpp b/Engine/source/platform/nativeDialogs/fileDialog.cpp index 34e57e3e6..ad8bdfafb 100644 --- a/Engine/source/platform/nativeDialogs/fileDialog.cpp +++ b/Engine/source/platform/nativeDialogs/fileDialog.cpp @@ -122,6 +122,7 @@ FileDialog::FileDialog() : mData() // Default to File Must Exist Open Dialog style mData.mStyle = FileDialogData::FDS_OPEN | FileDialogData::FDS_MUSTEXIST; mChangePath = false; + mForceRelativePath = true; } FileDialog::~FileDialog() @@ -151,6 +152,8 @@ void FileDialog::initPersistFields() addProtectedField("changePath", TypeBool, Offset(mChangePath, FileDialog), &setChangePath, &getChangePath, "True/False whether to set the working directory to the directory returned by the dialog."); + addField("forceRelativePath", TypeBool, Offset(mForceRelativePath, FileDialog), "True/False whether to the path returned is always made to be relative."); + Parent::initPersistFields(); } @@ -267,7 +270,8 @@ bool FileDialog::Execute() } String resultPath = String(outPath).replace(rootDir, String("")); - resultPath = resultPath.replace(0, 1, String("")).c_str(); //kill '\\' prefix + if(resultPath[0] == '\\') + resultPath = resultPath.replace(0, 1, String("")).c_str(); //kill '\\' prefix resultPath = resultPath.replace(String("\\"), String("/")); // Did we select a file? @@ -280,7 +284,10 @@ bool FileDialog::Execute() if (mData.mStyle & FileDialogData::FDS_OPEN || mData.mStyle & FileDialogData::FDS_SAVE) { // Single file selection, do it the easy way - mData.mFile = Platform::makeRelativePathName(resultPath.c_str(), NULL); + if(mForceRelativePath) + mData.mFile = Platform::makeRelativePathName(resultPath.c_str(), NULL); + else + mData.mFile = resultPath.c_str(); } else if (mData.mStyle & FileDialogData::FDS_MULTIPLEFILES) { @@ -300,7 +307,11 @@ bool FileDialog::Execute() else { //nope, just one file, so set it as normal - setDataField(StringTable->insert("files"), "0", Platform::makeRelativePathName(resultPath.c_str(), NULL)); + if (mForceRelativePath) + setDataField(StringTable->insert("files"), "0", Platform::makeRelativePathName(resultPath.c_str(), NULL)); + else + setDataField(StringTable->insert("files"), "0", resultPath.c_str()); + setDataField(StringTable->insert("fileCount"), NULL, "1"); } } diff --git a/Engine/source/platform/nativeDialogs/fileDialog.h b/Engine/source/platform/nativeDialogs/fileDialog.h index b5b4ed618..7c08b51ae 100644 --- a/Engine/source/platform/nativeDialogs/fileDialog.h +++ b/Engine/source/platform/nativeDialogs/fileDialog.h @@ -106,6 +106,7 @@ protected: FileDialogData mData; ///< Stores platform agnostic information about the dialogs properties bool mChangePath; ///< Exposed ChangePath Property bool mBoolTranslator; ///< Internally used to translate boolean values into their respective bits of dialog style + bool mForceRelativePath; public: FileDialog(); diff --git a/Engine/source/platformSDL/menus/PlatformSDLPopupMenuData.h b/Engine/source/platformSDL/menus/PlatformSDLPopupMenuData.h deleted file mode 100644 index 4911f5c10..000000000 --- a/Engine/source/platformSDL/menus/PlatformSDLPopupMenuData.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef PLATFORM_SDL_POPUPMENU_DATA_H -#define PLATFORM_SDL_POPUPMENU_DATA_H - -#include "core/util/tDictionary.h" - -class GuiMenuBar; -struct EventDescriptor; -class PopupMenu; -class MenuBar; - -struct PlatformPopupMenuData -{ - MenuBar *mMenuBar; - GuiMenuBar::Menu *mMenuGui; - - static const U8 mCheckedBitmapIdx = 0; - static Map mMenuMap; - - PlatformPopupMenuData() - { - mMenuBar = NULL; - mMenuGui = NULL; - } - - ~PlatformPopupMenuData() - { - - } - - void insertAccelerator(EventDescriptor &desc, U32 id); - void removeAccelerator(U32 id); - void setAccelleratorEnabled(U32 id, bool enabled); -}; - -#endif //PLATFORM_SDL_POPUPMENU_DATA_H \ No newline at end of file diff --git a/Engine/source/platformSDL/menus/menuBarSDL.cpp b/Engine/source/platformSDL/menus/menuBarSDL.cpp deleted file mode 100644 index a0ddb2370..000000000 --- a/Engine/source/platformSDL/menus/menuBarSDL.cpp +++ /dev/null @@ -1,200 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/menus/menuBar.h" -#include "platform/menus/popupMenu.h" -#include "gui/core/guiCanvas.h" -#include "windowManager/platformWindowMgr.h" -#include "core/util/safeDelete.h" - -#include "windowManager/sdl/sdlWindow.h" -#include "gui/editor/guiMenuBar.h" - -#include "platformSDL/menus/PlatformSDLPopupMenuData.h" - -#include "platformSDL/menus/guiPlatformGenericMenuBar.h" - -#ifdef TORQUE_SDL - -//----------------------------------------------------------------------------- -// Platform Data -//----------------------------------------------------------------------------- - -// class PlatformMenuBarData -// { -// -// }; - -Map PlatformPopupMenuData::mMenuMap; - -IMPLEMENT_CONOBJECT(GuiPlatformGenericMenuBar); - -//----------------------------------------------------------------------------- -// MenuBar Methods -//----------------------------------------------------------------------------- - -void MenuBar::createPlatformPopupMenuData() -{ - mData = NULL; -} - -void MenuBar::deletePlatformPopupMenuData() -{ -// SAFE_DELETE(mData); -} - -//----------------------------------------------------------------------------- - -GuiPlatformGenericMenuBar* _FindMenuBarCtrl() -{ - GuiControl* control; - Sim::findObject("PlatformGenericMenubar", control); - AssertFatal(control, ""); - if( !control ) - return NULL; - - GuiPlatformGenericMenuBar* menuBar; - menuBar = dynamic_cast( control->findObjectByInternalName( StringTable->insert("menubar"), true) ); - AssertFatal(menuBar, ""); - return menuBar; -} - - -void MenuBar::updateMenuBar(PopupMenu *popupMenu /* = NULL */) -{ - //if(! isAttachedToCanvas()) - // return; - - if(!popupMenu) - return; - - GuiPlatformGenericMenuBar* menuBarGui = _FindMenuBarCtrl(); - popupMenu->mData->mMenuBar = this; - - String menuTitle = popupMenu->getBarTitle(); - - //Next, find out if we're still in the list of entries - SimSet::iterator itr = find(begin(), end(), popupMenu); - - GuiMenuBar::Menu* menuGui = menuBarGui->findMenu(menuTitle); - if (!menuGui) - { - //This is our first time setting this particular menu up, so we'll OK it. - if (itr == end()) - menuBarGui->attachToMenuBar(popupMenu->mData->mMenuGui); - else - menuBarGui->attachToMenuBar(popupMenu->mData->mMenuGui, itr - begin()); - } - else - { - //Not our first time through, so we're really updating it. - - //So, first, remove it from the menubar - menuBarGui->removeFromMenuBar(menuGui); - - //Next, find out if we're still in the list of entries - SimSet::iterator itr = find(begin(), end(), popupMenu); - - //if we're no longer in the list, we're pretty much done here - if (itr == end()) - return; - - //We're still here, so this is a valid menu for our current bar configuration, so add us back in. - menuBarGui->attachToMenuBar(menuGui, itr - begin()); - } -} - -//----------------------------------------------------------------------------- - -void MenuBar::attachToCanvas(GuiCanvas *owner, S32 pos) -{ - if(owner == NULL || isAttachedToCanvas()) - return; - - // This is set for popup menus in the onAttachToMenuBar() callback - mCanvas = owner; - - PlatformWindowSDL *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - - // Setup the native menu bar - GuiMenuBar *hWindowMenu = static_cast( pWindow->getMenuHandle() ); - if( hWindowMenu == NULL && !Journal::IsPlaying() ) - hWindowMenu = _FindMenuBarCtrl(); - - if(hWindowMenu) - { - pWindow->setMenuHandle( hWindowMenu ); - GuiControl *base = hWindowMenu->getParent(); - - while( base->getParent() ) - { - base = base->getParent(); - } - - mCanvas->setMenuBar( base ); - } - - for (S32 i = 0; i < size(); ++i) - { - PopupMenu *mnu = dynamic_cast(at(i)); - if (mnu == NULL) - { - Con::warnf("MenuBar::attachToMenuBar - Non-PopupMenu object in set"); - continue; - } - - if (mnu->isAttachedToMenuBar()) - mnu->removeFromMenuBar(); - - mnu->attachToMenuBar(owner, pos + i); - } - -} - -void MenuBar::removeFromCanvas() -{ - if (mCanvas == NULL || !isAttachedToCanvas()) - return; - - //_FindMenuBarCtrl()->clearMenus(); - - // Add the items - for (S32 i = 0; i < size(); ++i) - { - PopupMenu *mnu = dynamic_cast(at(i)); - if (mnu == NULL) - { - Con::warnf("MenuBar::removeFromMenuBar - Non-PopupMenu object in set"); - continue; - } - - mnu->removeFromMenuBar(); - } - - mCanvas->setMenuBar(NULL); - - mCanvas = NULL; -} - -#endif diff --git a/Engine/source/platformSDL/menus/popupMenuSDL.cpp b/Engine/source/platformSDL/menus/popupMenuSDL.cpp deleted file mode 100644 index 788d7c88e..000000000 --- a/Engine/source/platformSDL/menus/popupMenuSDL.cpp +++ /dev/null @@ -1,393 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifdef TORQUE_SDL - -#include "platform/menus/popupMenu.h" -#include "platform/menus/menuBar.h" -#include "console/consoleTypes.h" -#include "gui/core/guiCanvas.h" -#include "core/util/safeDelete.h" - -#include "sim/actionMap.h" -#include "platform/platformInput.h" - -#include "windowManager/sdl/sdlWindow.h" -#include "gui/editor/guiMenuBar.h" - -#include "platformSDL/menus/PlatformSDLPopupMenuData.h" -#include "console/engineAPI.h" - -#include "platformSDL/menus/guiPlatformGenericMenuBar.h" -#include "gui/editor/guiPopupMenuCtrl.h" - -////////////////////////////////////////////////////////////////////////// -// Platform Menu Data -////////////////////////////////////////////////////////////////////////// -GuiPlatformGenericMenuBar* findMenuBarCtrl() -{ - GuiControl* control; - Sim::findObject("PlatformGenericMenubar", control); - AssertFatal(control, ""); - if (!control) - return NULL; - - GuiPlatformGenericMenuBar* menuBar; - menuBar = dynamic_cast(control->findObjectByInternalName(StringTable->insert("menubar"), true)); - AssertFatal(menuBar, ""); - return menuBar; -} - -////////////////////////////////////////////////////////////////////////// - -void PlatformPopupMenuData::insertAccelerator(EventDescriptor &desc, U32 id) -{ - AssertFatal(0, ""); -} - -void PlatformPopupMenuData::removeAccelerator(U32 id) -{ - AssertFatal(0, ""); -} - -void PlatformPopupMenuData::setAccelleratorEnabled( U32 id, bool enabled ) -{ - AssertFatal(0, ""); -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::createPlatformPopupMenuData() -{ - mData = new PlatformPopupMenuData; -} - -void PopupMenu::deletePlatformPopupMenuData() -{ - SAFE_DELETE(mData); -} -void PopupMenu::createPlatformMenu() -{ - mData->mMenuGui = GuiMenuBar::sCreateMenu( getBarTitle(), getId() ); - PlatformPopupMenuData::mMenuMap[ mData->mMenuGui ] = this; -} - - -////////////////////////////////////////////////////////////////////////// -// Public Methods -////////////////////////////////////////////////////////////////////////// - -S32 PopupMenu::insertItem(S32 pos, const char *title, const char* accelerator, const char* cmd) -{ - GuiMenuBar::MenuItem *item = GuiMenuBar::findMenuItem( mData->mMenuGui, title ); - - //We'll make a special exception for the spacer items - if(item && dStrcmp(title, "")) - { - setItem( pos, title, accelerator, cmd); - return pos; - } - - item = GuiMenuBar::addMenuItem( mData->mMenuGui, title, pos, accelerator, -1, cmd ); - item->submenuParentMenu = this->mData->mMenuGui; - - return pos; -} - -S32 PopupMenu::insertSubMenu(S32 pos, const char *title, PopupMenu *submenu) -{ - GuiMenuBar::MenuItem *item = GuiMenuBar::addMenuItem( mData->mMenuGui, title, pos, "", -1, "" ); - item->isSubmenu = true; - item->submenu = submenu->mData->mMenuGui; - item->submenuParentMenu = this->mData->mMenuGui; - - return pos; -} - -bool PopupMenu::setItem(S32 pos, const char *title, const char* accelerator, const char* cmd) -{ - GuiMenuBar::MenuItem *item = NULL; - - item = GuiMenuBar::findMenuItem( mData->mMenuGui, title ); - - if(item) - { - item->id = pos; - item->cmd = cmd; - if( accelerator && accelerator[0] ) - item->accelerator = dStrdup( accelerator ); - else - item->accelerator = NULL; - return true; - } - - return false; -} - -void PopupMenu::removeItem(S32 itemPos) -{ - GuiMenuBar::MenuItem *item = GuiMenuBar::findMenuItem( mData->mMenuGui, String::ToString(itemPos) ); - if(item) - { - GuiMenuBar::removeMenuItem( mData->mMenuGui, item); - } -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::enableItem( S32 pos, bool enable ) -{ - GuiMenuBar::MenuItem *item = NULL; - for( item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - { - if( item->id == pos) - item->enabled = enable; - } -} - -void PopupMenu::checkItem(S32 pos, bool checked) -{ - GuiMenuBar::MenuItem *item = NULL; - for( item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - if(item->id == pos) - break; - - if( !item ) - return; - - if(checked && item->checkGroup != -1) - { - // first, uncheck everything in the group: - for( GuiMenuBar::MenuItem *itemWalk = mData->mMenuGui->firstMenuItem; itemWalk; itemWalk = itemWalk->nextMenuItem ) - if( itemWalk->checkGroup == item->checkGroup && itemWalk->bitmapIndex == mData->mCheckedBitmapIdx ) - itemWalk->bitmapIndex = -1; - } - - item->bitmapIndex = checked ? mData->mCheckedBitmapIdx : -1; -} - -void PopupMenu::checkRadioItem(S32 firstPos, S32 lastPos, S32 checkPos) -{ - GuiMenuBar::MenuItem *item = NULL; - for( item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - { - if(item->id >= firstPos && item->id <= lastPos) - { - item->bitmapIndex = (item->id == checkPos) ? mData->mCheckedBitmapIdx : -1; - } - } -} - -bool PopupMenu::isItemChecked(S32 pos) -{ - GuiMenuBar::MenuItem *item = NULL; - for( item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - if(item->id == pos) - return item->bitmapIndex == mData->mCheckedBitmapIdx; - - return false; -} - -U32 PopupMenu::getItemCount() -{ - int count = 0; - for( GuiMenuBar::MenuItem *item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - ++count; - - return count; -} - -////////////////////////////////////////////////////////////////////////// - -bool PopupMenu::canHandleID(U32 id) -{ - return true; -} - -bool PopupMenu::handleSelect(U32 command, const char *text /* = NULL */) -{ - return dAtob(Con::executef(this, "onSelectItem", Con::getIntArg(command), text ? text : "")); -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::showPopup(GuiCanvas *owner, S32 x /* = -1 */, S32 y /* = -1 */) -{ - if(owner == NULL) - return; - - GuiControl* editorGui; - Sim::findObject("EditorGui", editorGui); - - if (editorGui) - { - GuiPopupMenuTextListCtrl* textList; - GuiPopupMenuBackgroundCtrl* backgroundCtrl; - Sim::findObject("PopUpMenuControl", backgroundCtrl); - - GuiControlProfile* profile; - Sim::findObject("GuiMenubarProfile", profile); - - if (!profile) - return; - - if (!backgroundCtrl) - { - textList = new GuiPopupMenuTextListCtrl(); - - textList->registerObject(); - - backgroundCtrl = new GuiPopupMenuBackgroundCtrl(textList); - - backgroundCtrl->registerObject("PopUpMenuControl"); - - textList->setControlProfile(profile); - - backgroundCtrl->addObject(textList); - } - else - { - textList = dynamic_cast(backgroundCtrl->first()); - } - - if (!backgroundCtrl || !textList) - return; - - owner->pushDialogControl(backgroundCtrl, 10); - - backgroundCtrl->setExtent(editorGui->getExtent()); - - textList->clear(); - textList->mMenu = mData->mMenuGui; - textList->mMenuBar = findMenuBarCtrl(); - textList->mPopup = this; - - S32 textWidth = 0, width = 0; - S32 acceleratorWidth = 0; - GFont *font = profile->mFont; - - Point2I maxBitmapSize = Point2I(0, 0); - - S32 numBitmaps = profile->mBitmapArrayRects.size(); - if (numBitmaps) - { - RectI *bitmapBounds = profile->mBitmapArrayRects.address(); - for (S32 i = 0; i < numBitmaps; i++) - { - if (bitmapBounds[i].extent.x > maxBitmapSize.x) - maxBitmapSize.x = bitmapBounds[i].extent.x; - if (bitmapBounds[i].extent.y > maxBitmapSize.y) - maxBitmapSize.y = bitmapBounds[i].extent.y; - } - } - - for (GuiMenuBar::MenuItem *walk = mData->mMenuGui->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if (!walk->visible) - continue; - - S32 iTextWidth = font->getStrWidth(walk->text); - S32 iAcceleratorWidth = walk->accelerator ? font->getStrWidth(walk->accelerator) : 0; - - if (iTextWidth > textWidth) - textWidth = iTextWidth; - if (iAcceleratorWidth > acceleratorWidth) - acceleratorWidth = iAcceleratorWidth; - } - width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4; - - textList->setCellSize(Point2I(width, font->getHeight() + 2)); - textList->clearColumnOffsets(); - textList->addColumnOffset(-1); // add an empty column in for the bitmap index. - textList->addColumnOffset(maxBitmapSize.x + 1); - textList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4); - - U32 entryCount = 0; - - for (GuiMenuBar::MenuItem *walk = mData->mMenuGui->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if (!walk->visible) - continue; - - char buf[512]; - - // If this menu item is a submenu, then set the isSubmenu to 2 to indicate - // an arrow should be drawn. Otherwise set the isSubmenu normally. - char isSubmenu = 1; - if (walk->isSubmenu) - isSubmenu = 2; - - char bitmapIndex = 1; - if (walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= profile->mBitmapArrayRects.size())) - bitmapIndex = walk->bitmapIndex + 2; - dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, walk->text, walk->accelerator ? walk->accelerator : ""); - textList->addEntry(entryCount, buf); - - if (!walk->enabled) - textList->setEntryActive(entryCount, false); - - entryCount++; - } - - Point2I pos = owner->getCursorPos(); - textList->setPosition(pos); - - //nudge in if we'd overshoot the screen - S32 widthDiff = (textList->getPosition().x + textList->getExtent().x) - backgroundCtrl->getWidth(); - if (widthDiff > 0) - { - Point2I popupPos = textList->getPosition(); - textList->setPosition(popupPos.x - widthDiff, popupPos.y); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::attachToMenuBar(GuiCanvas *owner, S32 pos, const char *title) -{ - if(owner == NULL || isAttachedToMenuBar()) - return; -} - -// New version of above for use by MenuBar class. Do not use yet. -void PopupMenu::attachToMenuBar(GuiCanvas *owner, S32 pos) -{ - if(owner == NULL || isAttachedToMenuBar()) - return; - - //mData->mMenuBar = owner->setMenuBar(); -} - -void PopupMenu::removeFromMenuBar() -{ - if(isAttachedToMenuBar()) - return; -} - -S32 PopupMenu::getPosOnMenuBar() -{ - - return 0; -} - -#endif diff --git a/Engine/source/platformWin32/menus/menuBarWin32.cpp b/Engine/source/platformWin32/menus/menuBarWin32.cpp deleted file mode 100644 index dfa103161..000000000 --- a/Engine/source/platformWin32/menus/menuBarWin32.cpp +++ /dev/null @@ -1,177 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platformWin32/platformWin32.h" -#include "platform/menus/menuBar.h" -#include "platform/menus/popupMenu.h" -#include "gui/core/guiCanvas.h" -#include "windowManager/platformWindowMgr.h" -#include "windowManager/win32/win32Window.h" -#include "core/util/safeDelete.h" - -//----------------------------------------------------------------------------- -// Platform Data -//----------------------------------------------------------------------------- - -// class PlatformMenuBarData -// { -// -// }; - -//----------------------------------------------------------------------------- -// MenuBar Methods -//----------------------------------------------------------------------------- - -#ifndef TORQUE_SDL - -void MenuBar::createPlatformPopupMenuData() -{ -// mData = new PlatformMenuBarData; - - // [tom, 6/4/2007] Nothing currently needed for win32 - mData = NULL; -} - -void MenuBar::deletePlatformPopupMenuData() -{ -// SAFE_DELETE(mData); -} - -//----------------------------------------------------------------------------- - -void MenuBar::updateMenuBar(PopupMenu *menu /* = NULL */) -{ - if(! isAttachedToCanvas()) - return; - - if(menu == NULL) - { - // [tom, 6/4/2007] Kludgetastic - GuiCanvas *oldCanvas = mCanvas; - S32 pos = -1; - PopupMenu *mnu = dynamic_cast(at(0)); - if(mnu) - pos = mnu->getPosOnMenuBar(); - - removeFromCanvas(); - attachToCanvas(oldCanvas, pos); - - return; - } - - menu->removeFromMenuBar(); - SimSet::iterator itr = find(begin(), end(), menu); - if(itr == end()) - return; - - menu->attachToMenuBar(mCanvas, itr - begin()); - - Win32Window *pWindow = dynamic_cast(mCanvas->getPlatformWindow()); - if(pWindow == NULL) - return; - - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); -} - -//----------------------------------------------------------------------------- - -void MenuBar::attachToCanvas(GuiCanvas *owner, S32 pos) -{ - if(owner == NULL || isAttachedToCanvas()) - return; - - // This is set for popup menus in the onAttachToMenuBar() callback - mCanvas = owner; - - Win32Window *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - - // Setup the native menu bar - HMENU hWindowMenu = pWindow->getMenuHandle(); - if(hWindowMenu == NULL && !Journal::IsPlaying()) - { - hWindowMenu = CreateMenu(); - if(hWindowMenu) - { - pWindow->setMenuHandle( hWindowMenu); - } - } - - // Add the items - for(S32 i = 0;i < size();++i) - { - PopupMenu *mnu = dynamic_cast(at(i)); - if(mnu == NULL) - { - Con::warnf("MenuBar::attachToMenuBar - Non-PopupMenu object in set"); - continue; - } - - if(mnu->isAttachedToMenuBar()) - mnu->removeFromMenuBar(); - - mnu->attachToMenuBar(owner, pos + i); - } - - HWND hWindow = pWindow->getHWND(); - SetMenu(hWindow, hWindowMenu); - DrawMenuBar(hWindow); - -} - -void MenuBar::removeFromCanvas() -{ - if(mCanvas == NULL || ! isAttachedToCanvas()) - return; - - Win32Window *pWindow = dynamic_cast(mCanvas->getPlatformWindow()); - if(pWindow == NULL) - return; - - // Setup the native menu bar - HMENU hWindowMenu = pWindow->getMenuHandle(); - if(hWindowMenu == NULL) - return; - - // Add the items - for(S32 i = 0;i < size();++i) - { - PopupMenu *mnu = dynamic_cast(at(i)); - if(mnu == NULL) - { - Con::warnf("MenuBar::removeFromMenuBar - Non-PopupMenu object in set"); - continue; - } - - mnu->removeFromMenuBar(); - } - - HWND hWindow = pWindow->getHWND(); - SetMenu(hWindow, NULL); - DrawMenuBar(hWindow); - - mCanvas = NULL; -} - -#endif diff --git a/Engine/source/platformWin32/menus/popupMenuWin32.cpp b/Engine/source/platformWin32/menus/popupMenuWin32.cpp deleted file mode 100644 index fc3170eeb..000000000 --- a/Engine/source/platformWin32/menus/popupMenuWin32.cpp +++ /dev/null @@ -1,746 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef TORQUE_SDL - -#include "platform/menus/popupMenu.h" -#include "platformWin32/platformWin32.h" -#include "console/engineAPI.h" -#include "console/consoleTypes.h" -#include "gui/core/guiCanvas.h" -#include "windowManager/platformWindowMgr.h" -#include "windowManager/win32/win32Window.h" -#include "core/util/safeDelete.h" - -#include "sim/actionMap.h" -#include "platform/platformInput.h" - -////////////////////////////////////////////////////////////////////////// -// Platform Menu Data -////////////////////////////////////////////////////////////////////////// - -struct PlatformPopupMenuData -{ - static U32 mLastPopupMenuID; - static const U32 PopupMenuIDRange; - - HMENU mMenu; - U32 mMenuID; - U32 mLastID; - - Win32Window::AcceleratorList mAccelerators; - Win32Window::AcceleratorList mDisabledAccelerators; - - PlatformPopupMenuData() - { - mMenu = NULL; - mMenuID = mLastPopupMenuID++; - mLastID = 0; - } - - ~PlatformPopupMenuData() - { - if(mMenu) - DestroyMenu(mMenu); - } - - void insertAccelerator(EventDescriptor &desc, U32 id); - void removeAccelerator(U32 id); - void setAccelleratorEnabled(U32 id, bool enabled); -}; - -U32 PlatformPopupMenuData::mLastPopupMenuID = 0; -const U32 PlatformPopupMenuData::PopupMenuIDRange = 100; - -////////////////////////////////////////////////////////////////////////// - -void PlatformPopupMenuData::insertAccelerator(EventDescriptor &desc, U32 id) -{ - if(desc.eventType != SI_KEY) - return; - - Win32Window::AcceleratorList::iterator i; - for(i = mAccelerators.begin();i != mAccelerators.end();++i) - { - if(i->mID == id) - { - // Update existing entry - i->mDescriptor.eventType = desc.eventType; - i->mDescriptor.eventCode = desc.eventCode; - i->mDescriptor.flags = desc.flags; - return; - } - - if(i->mDescriptor.eventType == desc.eventType && i->mDescriptor.eventCode == desc.eventCode && i->mDescriptor.flags == desc.flags) - { - // Already have a matching accelerator, don't add another one - return; - } - } - - Win32Window::Accelerator accel; - accel.mDescriptor = desc; - accel.mID = id; - mAccelerators.push_back(accel); -} - -void PlatformPopupMenuData::removeAccelerator(U32 id) -{ - Win32Window::AcceleratorList::iterator i; - for(i = mAccelerators.begin();i != mAccelerators.end();++i) - { - if(i->mID == id) - { - mAccelerators.erase(i); - return; - } - } -} - -void PlatformPopupMenuData::setAccelleratorEnabled( U32 id, bool enabled ) -{ - Win32Window::AcceleratorList *src = NULL; - Win32Window::AcceleratorList *dst = NULL; - - if ( enabled ) - { - src = &mDisabledAccelerators; - dst = &mAccelerators; - } - else - { - src = &mAccelerators; - dst = &mDisabledAccelerators; - } - - Win32Window::AcceleratorList::iterator i; - for ( i = src->begin(); i != src->end(); ++i ) - { - if ( i->mID == id ) - { - Win32Window::Accelerator tmp = *i; - src->erase( i ); - dst->push_back( tmp ); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::createPlatformPopupMenuData() -{ - mData = new PlatformPopupMenuData; -} - -void PopupMenu::deletePlatformPopupMenuData() -{ - SAFE_DELETE(mData); -} -void PopupMenu::createPlatformMenu() -{ - mData->mMenu = mIsPopup ? CreatePopupMenu() : CreateMenu(); - AssertFatal(mData->mMenu, "Unable to create menu"); - - MENUINFO mi = { 0 }; - mi.cbSize = sizeof(mi); - mi.fMask = MIM_MENUDATA; - mi.dwMenuData = (ULONG_PTR)this; - SetMenuInfo(mData->mMenu, &mi); -} - -////////////////////////////////////////////////////////////////////////// -// Public Methods -////////////////////////////////////////////////////////////////////////// - -S32 PopupMenu::insertItem(S32 pos, const char *title, const char* accelerator, const char *) -{ - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - bool isAttached = isAttachedToMenuBar(); - if(isAttached && pWindow == NULL) - return -1; - - MENUITEMINFOA mi = { 0 }; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_ID|MIIM_TYPE; - mi.wID = (mData->mMenuID * PlatformPopupMenuData::PopupMenuIDRange) + mData->mLastID + 1; - mData->mLastID++; - if(title && *title) - mi.fType = MFT_STRING; - else - mi.fType = MFT_SEPARATOR; - - char buf[1024]; - if(accelerator && *accelerator) - { - dSprintf(buf, sizeof(buf), "%s\t%s", title, accelerator); - - if(isAttached) - pWindow->removeAccelerators(mData->mAccelerators); - - // Build entry for accelerator table - EventDescriptor accelDesc; - if(ActionMap::createEventDescriptor(accelerator, &accelDesc)) - mData->insertAccelerator(accelDesc, mi.wID); - else - Con::errorf("PopupMenu::insertItem - Could not create event descriptor for accelerator \"%s\"", accelerator); - - if(isAttached) - pWindow->addAccelerators(mData->mAccelerators); - } - else - dSprintf(buf, sizeof(buf), "%s", title); - - mi.dwTypeData = (LPSTR)buf; - - if(InsertMenuItemA(mData->mMenu, pos, TRUE, &mi)) - { - if(isAttached) - { - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - } - return mi.wID; - } - - return -1; -} - -S32 PopupMenu::insertSubMenu(S32 pos, const char *title, PopupMenu *submenu) -{ - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - bool isAttached = isAttachedToMenuBar(); - if(isAttached && pWindow == NULL) - return -1; - - for(S32 i = 0;i < mSubmenus->size();i++) - { - if(submenu == (*mSubmenus)[i]) - { - Con::errorf("PopupMenu::insertSubMenu - Attempting to add submenu twice"); - return -1; - } - } - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_ID|MIIM_TYPE|MIIM_SUBMENU|MIIM_DATA; - mi.wID = (mData->mMenuID * PlatformPopupMenuData::PopupMenuIDRange) + mData->mLastID + 1; - if(title && *title) - mi.fType = MFT_STRING; - else - mi.fType = MFT_SEPARATOR; - mi.dwTypeData = (LPSTR)title; - mi.hSubMenu = submenu->mData->mMenu; - mi.dwItemData = (ULONG_PTR)submenu; - if(InsertMenuItemA(mData->mMenu, pos, TRUE, &mi)) - { - mSubmenus->addObject(submenu); - - if(isAttached) - { - pWindow->addAccelerators(submenu->mData->mAccelerators); - - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - } - return mi.wID; - } - - return -1; -} - -bool PopupMenu::setItem(S32 pos, const char *title, const char* accelerator, const char *) -{ - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - bool isAttached = isAttachedToMenuBar(); - if(isAttached && pWindow == NULL) - return false; - - // Are we out of range? - if ( pos >= getItemCount() ) - return false; - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_TYPE; - - if(title && *title) - mi.fType = MFT_STRING; - else - mi.fType = MFT_SEPARATOR; - - char buf[1024]; - if(accelerator && *accelerator) - { - dSprintf(buf, sizeof(buf), "%s\t%s", title, accelerator); - - if(isAttached) - pWindow->removeAccelerators(mData->mAccelerators); - - // Build entry for accelerator table - EventDescriptor accelDesc; - if(ActionMap::createEventDescriptor(accelerator, &accelDesc)) - mData->insertAccelerator(accelDesc, pos); - else - Con::errorf("PopupMenu::setItem - Could not create event descriptor for accelerator \"%s\"", accelerator); - - if(isAttached) - pWindow->addAccelerators(mData->mAccelerators); - } - else - dSprintf(buf, sizeof(buf), "%s", title); - - mi.dwTypeData = (LPSTR)buf; - - if(SetMenuItemInfoA(mData->mMenu, pos, TRUE, &mi)) - { - if(isAttached) - { - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - } - - return true; - } - - return false; -} - -void PopupMenu::removeItem(S32 itemPos) -{ - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - bool isAttached = isAttachedToMenuBar(); - if(isAttached && pWindow == NULL) - return; - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_DATA|MIIM_ID; - if(GetMenuItemInfoA(mData->mMenu, itemPos, TRUE, &mi)) - { - bool submenu = false; - - // Update list of submenus if this is a submenu - if(mi.fMask & MIIM_DATA) - { - PopupMenu *mnu = (PopupMenu *)mi.dwItemData; - if( mnu != NULL ) - { - if(isAttached) - pWindow->removeAccelerators(mnu->mData->mAccelerators); - mSubmenus->removeObject(mnu); - - submenu = true; - } - } - - if(! submenu) - { - // Update accelerators if this has an accelerator and wasn't a sub menu - for(S32 i = 0;i < mData->mAccelerators.size();++i) - { - if(mData->mAccelerators[i].mID == mi.wID) - { - if(isAttached) - pWindow->removeAccelerators(mData->mAccelerators); - - mData->mAccelerators.erase(i); - - if(isAttached) - pWindow->addAccelerators(mData->mAccelerators); - - break; - } - } - } - } - else - return; - - RemoveMenu(mData->mMenu, itemPos, MF_BYPOSITION); - - if(isAttached) - { - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - } -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::enableItem( S32 pos, bool enable ) -{ - U32 flags = enable ? MF_ENABLED : MF_GRAYED; - EnableMenuItem( mData->mMenu, pos, MF_BYPOSITION|flags ); - - // Update accelerators. - - // NOTE: This really DOES need to happen. A disabled menu item - // should not still have an accelerator mapped to it. - // - // Unfortunately, the editors currently only set menu items - // enabled/disabled when the menu itself is selected which means our - // accelerators would be out of synch. - - /* - Win32Window *pWindow = mCanvas ? dynamic_cast( mCanvas->getPlatformWindow() ) : NULL; - bool isAttached = isAttachedToMenuBar(); - if ( isAttached && pWindow == NULL ) - return; - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_DATA|MIIM_ID; - if ( !GetMenuItemInfoA( mData->mMenu, pos, TRUE, &mi) ) - return; - - if ( isAttached ) - pWindow->removeAccelerators( mData->mAccelerators ); - - mData->setAccelleratorEnabled( mi.wID, enable ); - - if ( isAttached ) - pWindow->addAccelerators( mData->mAccelerators ); - */ -} - -void PopupMenu::checkItem(S32 pos, bool checked) -{ -// U32 flags = checked ? MF_CHECKED : MF_UNCHECKED; -// CheckMenuItem(mData->mMenu, pos, MF_BYPOSITION|flags); - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_STATE; - mi.fState = checked ? MFS_CHECKED : MFS_UNCHECKED; - SetMenuItemInfoA(mData->mMenu, pos, TRUE, &mi); -} - -void PopupMenu::checkRadioItem(S32 firstPos, S32 lastPos, S32 checkPos) -{ - CheckMenuRadioItem(mData->mMenu, firstPos, lastPos, checkPos, MF_BYPOSITION); -} - -bool PopupMenu::isItemChecked(S32 pos) -{ - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_STATE; - if(GetMenuItemInfoA(mData->mMenu, pos, TRUE, &mi) && (mi.fState & MFS_CHECKED)) - return true; - return false; -} - -U32 PopupMenu::getItemCount() -{ - return GetMenuItemCount( mData->mMenu ); -} - -////////////////////////////////////////////////////////////////////////// - -bool PopupMenu::canHandleID(U32 id) -{ - for(S32 i = 0;i < mSubmenus->size();i++) - { - PopupMenu *subM = dynamic_cast((*mSubmenus)[i]); - if(subM == NULL) - continue; - - if(subM->canHandleID(id)) - return true; - } - - if(id >= mData->mMenuID * PlatformPopupMenuData::PopupMenuIDRange && - id < (mData->mMenuID+1) * PlatformPopupMenuData::PopupMenuIDRange) - { - return true; - } - - return false; -} - -bool PopupMenu::handleSelect(U32 command, const char *text /* = NULL */) -{ - // [tom, 8/20/2006] Pass off to a sub menu if it's for them - for(S32 i = 0;i < mSubmenus->size();i++) - { - PopupMenu *subM = dynamic_cast((*mSubmenus)[i]); - if(subM == NULL) - continue; - - if(subM->canHandleID(command)) - { - return subM->handleSelect(command, text); - } - } - - // [tom, 8/21/2006] Cheesey hack to find the position based on ID - char buf[512]; - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.dwTypeData = NULL; - - S32 numItems = GetMenuItemCount(mData->mMenu); - S32 pos = -1; - for(S32 i = 0;i < numItems;i++) - { - mi.fMask = MIIM_ID|MIIM_STRING|MIIM_STATE; - if(GetMenuItemInfoA(mData->mMenu, i, TRUE, &mi)) - { - if(mi.wID == command) - { - if(text == NULL) - { - mi.dwTypeData = buf; - mi.cch++; - GetMenuItemInfoA(mData->mMenu, i, TRUE, &mi); - - // [tom, 5/11/2007] Don't do anything if the menu item is disabled - if(mi.fState & MFS_DISABLED) - return false; - - text = StringTable->insert(mi.dwTypeData); - } - pos = i; - break; - } - } - } - - if(pos == -1) - { - Con::errorf("PopupMenu::handleSelect - Could not find menu item position for ID %d ... this shouldn't happen!", command); - return false; - } - - // [tom, 8/20/2006] Wasn't handled by a submenu, pass off to script - return dAtob(Con::executef(this, "onSelectItem", Con::getIntArg(pos), text ? text : "")); -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::showPopup(GuiCanvas *owner, S32 x /* = -1 */, S32 y /* = -1 */) -{ - if( owner == NULL ) - { - Con::warnf("PopupMenu::showPopup - Invalid canvas supplied!"); - return; - } - - // [tom, 6/4/2007] showPopup() blocks until the menu is closed by the user, - // so the canvas pointer is not needed beyond the scope of this function - // when working with context menus. Setting mCanvas here will cause undesired - // behavior in relation to the menu bar. - - Win32Window *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - HWND hWindow = pWindow->getHWND(); - POINT p; - if(x == -1 && y == -1) - GetCursorPos(&p); - else - { - p.x = x; - p.y = y; - ClientToScreen(hWindow, &p); - } - - winState.renderThreadBlocked = true; - U32 opt = (int)TrackPopupMenu(mData->mMenu, TPM_NONOTIFY|TPM_RETURNCMD, p.x, p.y, 0, hWindow, NULL); - if(opt > 0) - handleSelect(opt, NULL); - winState.renderThreadBlocked = false; -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::attachToMenuBar(GuiCanvas *owner, S32 pos, const char *title) -{ - if(owner == NULL || isAttachedToMenuBar()) - return; - - // This is set for sub-menus in the onAttachToMenuBar() callback - mCanvas = owner; - - Win32Window *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - - HMENU hWindowMenu = pWindow->getMenuHandle(); - if(hWindowMenu == NULL) - { - hWindowMenu = CreateMenu(); - if(hWindowMenu) - { - pWindow->setMenuHandle( hWindowMenu); - } - } - - MENUITEMINFOA mii; - - mii.cbSize = sizeof(MENUITEMINFOA); - - mii.fMask = MIIM_STRING|MIIM_DATA; - mii.dwTypeData = (LPSTR)title; - mii.fMask |= MIIM_ID; - mii.wID = mData->mMenuID; - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = mData->mMenu; - mii.dwItemData = (ULONG_PTR)this; - - InsertMenuItemA(hWindowMenu, pos, TRUE, &mii); - - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - - pWindow->addAccelerators(mData->mAccelerators); - - // Add accelerators for sub menus - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *submenu = dynamic_cast(*i); - if(submenu == NULL) - continue; - - pWindow->addAccelerators(submenu->mData->mAccelerators); - } - - onAttachToMenuBar(owner, pos, title); -} - -// New version of above for use by MenuBar class. Do not use yet. -void PopupMenu::attachToMenuBar(GuiCanvas *owner, S32 pos) -{ - Win32Window *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - - //When playing a journal, the system menu is not actually shown - if (Journal::IsPlaying()) - { - onAttachToMenuBar(owner, pos, mBarTitle); - return; - } - - HMENU hWindowMenu = pWindow->getMenuHandle(); - - MENUITEMINFOA mii; - - mii.cbSize = sizeof(MENUITEMINFOA); - - mii.fMask = MIIM_STRING|MIIM_DATA; - mii.dwTypeData = (LPSTR)mBarTitle; - mii.fMask |= MIIM_ID; - mii.wID = mData->mMenuID; - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = mData->mMenu; - mii.dwItemData = (ULONG_PTR)this; - - InsertMenuItemA(hWindowMenu, pos, TRUE, &mii); - - pWindow->addAccelerators(mData->mAccelerators); - - // Add accelerators for sub menus (have to do this here as it's platform specific) - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *submenu = dynamic_cast(*i); - if(submenu == NULL) - continue; - - pWindow->addAccelerators(submenu->mData->mAccelerators); - } - - onAttachToMenuBar(owner, pos, mBarTitle); -} - -void PopupMenu::removeFromMenuBar() -{ - S32 pos = getPosOnMenuBar(); - if(pos == -1) - return; - - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - if(pWindow == NULL) - return; - - HMENU hMenuHandle = pWindow->getMenuHandle(); - if(!hMenuHandle) - return; - - RemoveMenu(hMenuHandle, pos, MF_BYPOSITION); - - HWND hWindow = pWindow->getHWND(); - - DrawMenuBar(hWindow); - - pWindow->removeAccelerators(mData->mAccelerators); - - // Remove accelerators for sub menus - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *submenu = dynamic_cast(*i); - if(submenu == NULL) - continue; - - pWindow->removeAccelerators(submenu->mData->mAccelerators); - } - - onRemoveFromMenuBar(mCanvas); -} - -S32 PopupMenu::getPosOnMenuBar() -{ - if(mCanvas == NULL) - return -1; - - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - if(pWindow == NULL) - return -1; - - HMENU hMenuHandle = pWindow->getMenuHandle(); - S32 numItems = GetMenuItemCount(hMenuHandle); - S32 pos = -1; - for(S32 i = 0;i < numItems;i++) - { - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_DATA; - if(GetMenuItemInfoA(hMenuHandle, i, TRUE, &mi)) - { - if(mi.fMask & MIIM_DATA) - { - PopupMenu *mnu = (PopupMenu *)mi.dwItemData; - if(mnu == this) - { - pos = i; - break; - } - } - } - } - - return pos; -} - -#endif \ No newline at end of file diff --git a/Engine/source/scene/sceneManager.cpp b/Engine/source/scene/sceneManager.cpp index e40caecfc..aeca87092 100644 --- a/Engine/source/scene/sceneManager.cpp +++ b/Engine/source/scene/sceneManager.cpp @@ -38,6 +38,9 @@ #include "T3D/gameBase/gameConnection.h" #include "math/mathUtils.h" +#include "T3D/components/render/renderComponentInterface.h" +#include "T3D/systems/render/meshRenderSystem.h" + // For player object bounds workaround. #include "T3D/player.h" @@ -358,6 +361,8 @@ void SceneManager::_renderScene( SceneRenderState* state, U32 objectMask, SceneZ if( gEditingMission && state->isDiffusePass() ) objectMask = EDITOR_RENDER_TYPEMASK; + MeshRenderSystem::render(this, state); + // Update the zoning state and traverse zones. if( getZoneManager() ) diff --git a/Engine/source/scene/sceneRenderState.cpp b/Engine/source/scene/sceneRenderState.cpp index fa1966ab8..3dda18513 100644 --- a/Engine/source/scene/sceneRenderState.cpp +++ b/Engine/source/scene/sceneRenderState.cpp @@ -106,17 +106,6 @@ void SceneRenderState::renderObjects( SceneObject** objects, U32 numObjects ) object->prepRenderImage( this ); } - U32 interfaceCount = RenderComponentInterface::all.size(); - for (U32 i = 0; i < RenderComponentInterface::all.size(); i++) - { - Component* comp = dynamic_cast(RenderComponentInterface::all[i]); - - if (comp->isClientObject() && comp->isActive()) - { - RenderComponentInterface::all[i]->prepRenderImage(this); - } - } - PROFILE_END(); // Render what the objects have batched. diff --git a/Engine/source/sim/netObject.cpp b/Engine/source/sim/netObject.cpp index e66a16940..7d821d5d5 100644 --- a/Engine/source/sim/netObject.cpp +++ b/Engine/source/sim/netObject.cpp @@ -581,4 +581,10 @@ void NetObject::addNetworkedField(const char* in_pFieldname, f.table = conType->getEnumTable(); sg_tempFieldList.push_back(f); +} + +DefineEngineMethod(NetObject, clearScopeAlways, void, (), , + "@brief Clears the scope always flag on this object.\n\n") +{ + object->clearScopeAlways(); } \ No newline at end of file diff --git a/Engine/source/ts/collada/colladaImport.cpp b/Engine/source/ts/collada/colladaImport.cpp index f3aea309e..1cc2909b0 100644 --- a/Engine/source/ts/collada/colladaImport.cpp +++ b/Engine/source/ts/collada/colladaImport.cpp @@ -198,7 +198,7 @@ DefineConsoleFunction( enumColladaForImport, bool, (const char * shapePath, cons for (S32 j = 0; j < libraryMats->getMaterial_array().getCount(); j++) { domMaterial* mat = libraryMats->getMaterial_array()[j]; - tree->insertItem(matsID, _GetNameOrId(mat), _GetNameOrId(mat), "", 0, 0); + tree->insertItem(matsID, _GetNameOrId(mat), "", "", 0, 0); } } @@ -256,5 +256,16 @@ DefineConsoleFunction( enumColladaForImport, bool, (const char * shapePath, cons else tree->setDataField(StringTable->insert("_upAxis"), 0, "Z_AXIS"); + char shapesStr[16]; + dSprintf(shapesStr, 16, "%i", stats.numMeshes); + char materialsStr[16]; + dSprintf(materialsStr, 16, "%i", stats.numMaterials); + char animationsStr[16]; + dSprintf(animationsStr, 16, "%i", stats.numClips); + + tree->setItemValue(nodesID, StringTable->insert(shapesStr)); + tree->setItemValue(matsID, StringTable->insert(materialsStr)); + tree->setItemValue(animsID, StringTable->insert(animationsStr)); + return true; } diff --git a/Engine/source/windowManager/sdl/sdlWindow.cpp b/Engine/source/windowManager/sdl/sdlWindow.cpp index a48e3743d..149825b98 100644 --- a/Engine/source/windowManager/sdl/sdlWindow.cpp +++ b/Engine/source/windowManager/sdl/sdlWindow.cpp @@ -27,7 +27,6 @@ #include "windowManager/sdl/sdlWindowMgr.h" #include "windowManager/sdl/sdlCursorController.h" #include "platformSDL/sdlInput.h" -#include "platform/menus/popupMenu.h" #include "platform/platformInput.h" #include "gfx/gfxDevice.h" diff --git a/Templates/BaseGame/game/core/CoreComponents.cs b/Templates/BaseGame/game/core/CoreComponents.cs new file mode 100644 index 000000000..5bdca8cd3 --- /dev/null +++ b/Templates/BaseGame/game/core/CoreComponents.cs @@ -0,0 +1,10 @@ + +function CoreComponentsModule::onCreate(%this) +{ + %classList = enumerateConsoleClasses( "Component" ); + + foreach$( %componentClass in %classList ) + { + echo("Native Component of type: " @ %componentClass); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/CoreComponents.module b/Templates/BaseGame/game/core/CoreComponents.module index 7ca29196a..0636e3bb5 100644 --- a/Templates/BaseGame/game/core/CoreComponents.module +++ b/Templates/BaseGame/game/core/CoreComponents.module @@ -2,6 +2,9 @@ ModuleId="CoreComponentsModule" VersionId="1" Description="Module that implements the core engine-level components for the game." + ScriptFile="CoreComponents.cs" + CreateFunction="onCreate" + DestroyFunction="onDestroy" Group="Game"> + description="Allows the component owner to operate as a camera." + scriptFile="core/components/game/camera.cs" /> diff --git a/Templates/BaseGame/game/core/components/game/controlObject.asset.taml b/Templates/BaseGame/game/core/components/game/controlObject.asset.taml index 93f58119f..19515e833 100644 --- a/Templates/BaseGame/game/core/components/game/controlObject.asset.taml +++ b/Templates/BaseGame/game/core/components/game/controlObject.asset.taml @@ -6,5 +6,5 @@ componentClass="Component" friendlyName="Control Object" componentType="Game" - scriptFile="core/components/game/controlObject.cs" - description="Allows the component owner to be controlled by a client." /> + description="Allows the component owner to be controlled by a client." + scriptFile="core/components/game/controlObject.cs" /> diff --git a/Templates/BaseGame/game/core/components/game/itemRotate.asset.taml b/Templates/BaseGame/game/core/components/game/itemRotate.asset.taml index 806d0db19..4c0c1bec4 100644 --- a/Templates/BaseGame/game/core/components/game/itemRotate.asset.taml +++ b/Templates/BaseGame/game/core/components/game/itemRotate.asset.taml @@ -6,5 +6,5 @@ componentClass="Component" friendlyName="Item Rotation" componentType="Game" - scriptFile="core/components/game/itemRotate.cs" - description="Rotates the entity around an axis, like an item pickup." /> + description="Rotates the entity around an axis, like an item pickup." + scriptFile="core/components/game/itemRotate.cs" /> diff --git a/Templates/BaseGame/game/core/components/game/playerSpawner.asset.taml b/Templates/BaseGame/game/core/components/game/playerSpawner.asset.taml index bf2b872ef..8a597aca4 100644 --- a/Templates/BaseGame/game/core/components/game/playerSpawner.asset.taml +++ b/Templates/BaseGame/game/core/components/game/playerSpawner.asset.taml @@ -6,5 +6,5 @@ componentClass="Component" friendlyName="Player Spawner" componentType="Game" - scriptFile="core/components/game/playerSpawner.cs" - description="When a client connects, it spawns a player object for them and attaches them to it." /> + description="When a client connects, it spawns a player object for them and attaches them to it." + scriptFile="core/components/game/playerSpawner.cs" /> diff --git a/Templates/BaseGame/game/core/helperFunctions.cs b/Templates/BaseGame/game/core/helperFunctions.cs index 855b5164a..1b98f1ea5 100644 --- a/Templates/BaseGame/game/core/helperFunctions.cs +++ b/Templates/BaseGame/game/core/helperFunctions.cs @@ -202,7 +202,7 @@ function updateTSShapeLoadProgress(%progress, %msg) { // Check if the loading GUI is visible and use that instead of the // separate import progress GUI if possible - if ( isObject(LoadingGui) && LoadingGui.isAwake() ) + /* if ( isObject(LoadingGui) && LoadingGui.isAwake() ) { // Save/Restore load progress at the start/end of the import process if ( %progress == 0 ) @@ -245,7 +245,7 @@ function updateTSShapeLoadProgress(%progress, %msg) %textCtrl.setText(%msg); } - Canvas.repaint(33); + Canvas.repaint(33);*/ } /// A helper function which will return the ghosted client object @@ -952,3 +952,207 @@ function TestPManager::testObjectRemove(%doNotSave) TestPManager.removeObjectFromFile(AudioSim); } +//Game Object management +function findGameObject(%name) +{ + //find all GameObjectAssets + %assetQuery = new AssetQuery(); + if(!AssetDatabase.findAssetType(%assetQuery, "GameObjectAsset")) + return 0; //if we didn't find ANY, just exit + + %count = %assetQuery.getCount(); + + for(%i=0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %assetName = AssetDatabase.getAssetName(%assetId); + + if(%assetName $= %name) + { + %gameObjectAsset = AssetDatabase.acquireAsset(%assetId); + + %assetQuery.delete(); + return %gameObjectAsset; + } + } + + %assetQuery.delete(); + return 0; +} + +function spawnGameObject(%name, %addToMissionGroup) +{ + if(%addToMissionGroup $= "") + %addToMissionGroup = true; + + //First, check if this already exists in our GameObjectPool + if(isObject(GameObjectPool)) + { + %goCount = GameObjectPool.countKey(%name); + + //if we have some already in the pool, pull it out and use that + if(%goCount != 0) + { + %goIdx = GameObjectPool.getIndexFromKey(%name); + %go = GameObjectPool.getValue(%goIdx); + + %go.setHidden(false); + %go.setScopeAlways(); + + if(%addToMissionGroup == true) //save instance when saving level + MissionGroup.add(%go); + else // clear instance on level exit + MissionCleanup.add(%go); + + //remove from the object pool's list + GameObjectPool.erase(%goIdx); + + return %go; + } + } + + //We have no existing pool, or no existing game objects of this type, so spawn a new one + + %gameObjectAsset = findGameObject(%name); + + if(isObject(%gameObjectAsset)) + { + %newSGOObject = TamlRead(%gameObjectAsset.TAMLFilePath); + + if(%addToMissionGroup == true) //save instance when saving level + MissionGroup.add(%newSGOObject); + else // clear instance on level exit + MissionCleanup.add(%newSGOObject); + + return %newSGOObject; + } + + return 0; +} + +function saveGameObject(%name, %tamlPath, %scriptPath) +{ + %gameObjectAsset = findGameObject(%name); + + //find if it already exists. If it does, we'll update it, if it does not, we'll make a new asset + if(isObject(%gameObjectAsset)) + { + %assetID = %gameObjectAsset.getAssetId(); + + %gameObjectAsset.TAMLFilePath = %tamlPath; + %gameObjectAsset.scriptFilePath = %scriptPath; + + TAMLWrite(%gameObjectAsset, AssetDatabase.getAssetFilePath(%assetID)); + AssetDatabase.refreshAsset(%assetID); + } + else + { + //Doesn't exist, so make a new one + %gameObjectAsset = new GameObjectAsset() + { + assetName = %name @ "Asset"; + gameObjectName = %name; + TAMLFilePath = %tamlPath; + scriptFilePath = %scriptPath; + }; + + //Save it alongside the taml file + %path = filePath(%tamlPath); + + TAMLWrite(%gameObjectAsset, %path @ "/" @ %name @ ".asset.taml"); + AssetDatabase.refreshAllAssets(true); + } +} + +//Allocates a number of a game object into a pool to be pulled from as needed +function allocateGameObjects(%name, %amount) +{ + //First, we need to make sure our pool exists + if(!isObject(GameObjectPool)) + { + new ArrayObject(GameObjectPool); + } + + //Next, we loop and generate our game objects, and add them to the pool + for(%i=0; %i < %amount; %i++) + { + %go = spawnGameObject(%name, false); + + //When our object is in the pool, it's not "real", so we need to make sure + //that we don't ghost it to clients untill we actually spawn it. + %go.clearScopeAlways(); + + //We also hide it, so that we don't 'exist' in the scene until we spawn + %go.hidden = true; + + //Lastly, add us to the pool, with the key being our game object type + GameObjectPool.add(%name, %go); + } +} + +function Entity::delete(%this) +{ + //we want to intercept the delete call, and add it to our GameObjectPool + //if it's a game object + if(%this.gameObjectAsset !$= "") + { + %this.setHidden(true); + %this.clearScopeAlways(); + + if(!isObject(GameObjectPool)) + { + new ArrayObject(GameObjectPool); + } + + GameObjectPool.add(%this.gameObjectAsset, %this); + + %missionSet = %this.getGroup(); + %missionSet.remove(%this); + } + else + { + %this.superClass.delete(); + } +} + +function clearGameObjectPool() +{ + if(isObject(GameObjectPool)) + { + %count = GameObjectPool.count(); + + for(%i=0; %i < %count; %i++) + { + %go = GameObjectPool.getValue(%i); + + %go.superClass.delete(); + } + + GameObjectPool.empty(); + } +} + +// +function switchCamera(%client, %newCamEntity) +{ + if(!isObject(%client) || !isObject(%newCamEntity)) + return error("SwitchCamera: No client or target camera!"); + + %cam = %newCamEntity.getComponent(CameraComponent); + + if(!isObject(%cam)) + return error("SwitchCamera: Target camera doesn't have a camera behavior!"); + + //TODO: Cleanup clientOwner for previous camera! + if(%cam.clientOwner == 0 || %cam.clientOwner $= "") + %cam.clientOwner = 0; + + %cam.scopeToClient(%client); + %cam.setDirty(); + + %client.setCameraObject(%newCamEntity); + %client.setControlCameraFov(%cam.FOV); + + %client.camera = %newCamEntity; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/ClientServer.cs b/Templates/BaseGame/game/data/clientServer/ClientServer.cs index 3cf7aaa55..e8530f22e 100644 --- a/Templates/BaseGame/game/data/clientServer/ClientServer.cs +++ b/Templates/BaseGame/game/data/clientServer/ClientServer.cs @@ -46,7 +46,7 @@ function ClientServer::destroy( %this ) disconnect(); // Destroy the physics plugin. - physicsDestroy(); + //physicsDestroy(); sfxShutdown(); diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/server.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/server.cs index 4fd007b35..9f30ecf5d 100644 --- a/Templates/BaseGame/game/data/clientServer/scripts/server/server.cs +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/server.cs @@ -25,11 +25,14 @@ function initServer() echo("\n--------- Initializing " @ $appName @ ": Server Scripts ---------"); //load prefs + + //Force-load the defaults just so we don't have any mistakes + exec( "data/clientServer/scripts/server/defaults.cs" ); + + //Then, if the user has saved preferences, we load those over-top the defaults %prefPath = getPrefpath(); if ( isFile( %prefPath @ "/serverPrefs.cs" ) ) exec( %prefPath @ "/serverPrefs.cs" ); - else - exec( "data/clientServer/scripts/server/defaults.cs" ); exec( "data/clientServer/scripts/server/audio.cs" ); exec( "data/clientServer/scripts/server/commands.cs" ); @@ -99,6 +102,11 @@ function createAndConnectToLocalServer( %serverType, %level ) { %conn.delete(); destroyServer(); + + MessageBoxOK("Error starting local server!", "There was an error when trying to connect to the local server."); + + if(isObject(MainMenuGui)) + Canvas.setContent(MainMenuGui); return false; } @@ -201,7 +209,7 @@ function destroyServer() // End any running levels and shut down the physics sim onServerDestroyed(); - physicsDestroy(); + //physicsDestroy(); // Delete all the server objects if (isObject(ServerGroup)) diff --git a/Templates/BaseGame/game/data/ui/scripts/chooseLevelDlg.cs b/Templates/BaseGame/game/data/ui/scripts/chooseLevelDlg.cs index c5ae1e297..af260c27d 100644 --- a/Templates/BaseGame/game/data/ui/scripts/chooseLevelDlg.cs +++ b/Templates/BaseGame/game/data/ui/scripts/chooseLevelDlg.cs @@ -31,29 +31,29 @@ function ChooseLevelDlg::onWake( %this ) %this->LevelDescriptionLabel.visible = false; %this->LevelDescription.visible = false; - %count = LevelFilesList.count(); + %assetQuery = new AssetQuery(); + AssetDatabase.findAssetType(%assetQuery, "LevelAsset"); + + %count = %assetQuery.getCount(); - if(%count == 0) + if(%count == 0 && !IsDirectory("tools")) { //We have no levels found. Prompt the user to open the editor to the default level if the tools are present - if(IsDirectory("tools")) - { - MessageBoxYesNo("Error", "No levels were found in any modules. Do you want to load the editor and start a new level?", - "fastLoadWorldEdit(1);", - "Canvas.popDialog(ChooseLevelDlg); if(isObject(ChooseLevelDlg.returnGui) && ChooseLevelDlg.returnGui.isMethod(\"onReturnTo\")) ChooseLevelDlg.returnGui.onReturnTo();"); - } - else - { - MessageBoxOK("Error", "No levels were found in any modules. Please ensure you have modules loaded that contain gameplay code and level files.", - "Canvas.popDialog(ChooseLevelDlg); if(isObject(ChooseLevelDlg.returnGui) && ChooseLevelDlg.returnGui.isMethod(\"onReturnTo\")) ChooseLevelDlg.returnGui.onReturnTo();"); - } - + MessageBoxOK("Error", "No levels were found in any modules. Please ensure you have modules loaded that contain gameplay code and level files.", + "Canvas.popDialog(ChooseLevelDlg); if(isObject(ChooseLevelDlg.returnGui) && ChooseLevelDlg.returnGui.isMethod(\"onReturnTo\")) ChooseLevelDlg.returnGui.onReturnTo();"); + + %assetQuery.delete(); return; } - for ( %i=0; %i < %count; %i++ ) - { - %file = LevelFilesList.getKey( %i ); + for(%i=0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %levelAsset = AssetDatabase.acquireAsset(%assetId); + + %file = %levelAsset.LevelFile; + if ( !isFile(%file @ ".mis") && !isFile(%file) ) continue; @@ -66,7 +66,7 @@ function ChooseLevelDlg::onWake( %this ) continue; } - %this.addMissionFile( %file ); + %this.addLevelAsset( %levelAsset ); } // Also add the new level mission as defined in the world editor settings @@ -218,6 +218,38 @@ function ChooseLevelDlg::addMissionFile( %this, %file ) CL_levelList.addRow( CL_levelList.rowCount(), %levelName TAB %file TAB %levelDesc TAB %levelPreview ); } +function ChooseLevelDlg::addLevelAsset( %this, %levelAsset ) +{ + %file = %levelAsset.LevelFile; + + /*%levelName = fileBase(%file); + %levelDesc = "A Torque level"; + + %LevelInfoObject = getLevelInfo(%file); + + if (%LevelInfoObject != 0) + { + if(%LevelInfoObject.levelName !$= "") + %levelName = %LevelInfoObject.levelName; + else if(%LevelInfoObject.name !$= "") + %levelName = %LevelInfoObject.name; + + if (%LevelInfoObject.desc0 !$= "") + %levelDesc = %LevelInfoObject.desc0; + + if (%LevelInfoObject.preview !$= "") + %levelPreview = %LevelInfoObject.preview; + + %LevelInfoObject.delete(); + }*/ + + %levelName = %levelAsset.friendlyName; + %levelDesc = %levelAsset.description; + %levelPreview = %levelAsset.levelPreviewImage; + + CL_levelList.addRow( CL_levelList.rowCount(), %levelName TAB %file TAB %levelDesc TAB %levelPreview ); +} + function ChooseLevelDlg::onSleep( %this ) { // This is set from the outside, only stays true for a single wake/sleep diff --git a/Templates/BaseGame/game/main.cs.in b/Templates/BaseGame/game/main.cs.in index 2ec150c0d..3eed267df 100644 --- a/Templates/BaseGame/game/main.cs.in +++ b/Templates/BaseGame/game/main.cs.in @@ -42,8 +42,11 @@ setNetPort(0); startFileChangeNotifications(); // If we have editors, initialize them here as well -if(isFile("tools/main.cs") && !$isDedicated) - exec("tools/main.cs"); +if (isToolBuild()) +{ + if(isFile("tools/main.cs") && !$isDedicated) + exec("tools/main.cs"); +} ModuleDatabase.setModuleExtension("module"); ModuleDatabase.scanModules( "data", false ); diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/animationIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/animationIcon.png new file mode 100644 index 000000000..381dcee84 Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/animationIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/clientScriptIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/clientScriptIcon.png new file mode 100644 index 000000000..3f83a2ff3 Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/clientScriptIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/componentIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/componentIcon.png new file mode 100644 index 000000000..cbaf56990 Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/componentIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/gameObjectIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/gameObjectIcon.png new file mode 100644 index 000000000..6b285daae Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/gameObjectIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/guiIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/guiIcon.png new file mode 100644 index 000000000..ffeb015f1 Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/guiIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/levelIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/levelIcon.png new file mode 100644 index 000000000..7fdb61d1b Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/levelIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/materialIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/materialIcon.png new file mode 100644 index 000000000..0e6c456a6 Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/materialIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/postEffectIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/postEffectIcon.png new file mode 100644 index 000000000..316cb2c83 Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/postEffectIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/scriptIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/scriptIcon.png new file mode 100644 index 000000000..1a2433dea Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/scriptIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/serverScriptIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/serverScriptIcon.png new file mode 100644 index 000000000..f65bccb39 Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/serverScriptIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/soundIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/soundIcon.png new file mode 100644 index 000000000..9705c33d8 Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/soundIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/stateMachineIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/stateMachineIcon.png new file mode 100644 index 000000000..95ef798ee Binary files /dev/null and b/Templates/BaseGame/game/tools/assetBrowser/art/stateMachineIcon.png differ diff --git a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml new file mode 100644 index 000000000..a442ab0a8 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/GameObjectCreator.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/GameObjectCreator.gui new file mode 100644 index 000000000..eb2bf15e6 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/GameObjectCreator.gui @@ -0,0 +1,217 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GameObjectCreator) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + selectedEntity = "20054"; + + new GuiWindowCtrl(CreateGameObjectWindow) { + text = "Create GameObject"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(GameObjectCreator);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "328 322"; + extent = "368 123"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl(GameObjectCreateBtn) { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "224 92"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_importAssetWindow.ImportAssets();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "292 92"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(GameObjectCreator);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(GameObjectCreatorObjectName) { + text = "Game Object Name:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 60"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Target Module:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(GameObjectCreatorPkgBtn) { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "342 27"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "Canvas.pushDialog(AssetBrowser_addModule);\nAssetBrowser_addModuleWindow.selectWindow();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(GameObjectModuleList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + text = "Characters"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 27"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(GameObjectCreatorName) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "116 60"; + extent = "234 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/addModuleWindow.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/addModuleWindow.gui new file mode 100644 index 000000000..e8f35a13a --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/addModuleWindow.gui @@ -0,0 +1,142 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_AddModule) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_addModuleWindow) { + text = "Create New Module"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "362 334"; + extent = "299 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "88 35"; + extent = "196 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ModuleName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Module Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 35"; + extent = "72 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "88 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addModuleWindow.CreateNewModule();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "220 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addModuleWindow.Close();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/addPackageWindow.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/addPackageWindow.gui new file mode 100644 index 000000000..48a48f5be --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/addPackageWindow.gui @@ -0,0 +1,142 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_AddPackage) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_addPackageWindow) { + text = "Create New Package"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "362 334"; + extent = "299 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "88 35"; + extent = "196 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "PackageName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Package Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 35"; + extent = "72 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "88 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addPackageWindow.CreateNewPackage();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "220 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addPackageWindow.Close();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui new file mode 100644 index 000000000..fd06f7561 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui @@ -0,0 +1,934 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + AddNewArtAssetPopup = "18801"; + AddNewAssetPopup = "18802"; + AddNewScriptAssetPopup = "18800"; + currentPreviewPage = "0"; + enabled = "1"; + importAssetFinalListArray = "20465"; + importAssetNewListArray = "20463"; + importAssetUnprocessedListArray = "20464"; + totalPages = "1"; + + new GuiWindowCtrl(AssetBrowser_addFilterWindow) { + text = "Create New Tag"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "321 334"; + extent = "381 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "64 35"; + extent = "196 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "tagName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Tag Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 35"; + extent = "52 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "64 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.createFilter( AssetBrowser_addFilterWindow-->tagName.getText() );AssetBrowser_addFilterWindow.setVisible(0);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "196 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addFilterWindow.setVisible(0);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiWindowCtrl(AssetBrowserWindow) { + text = "Asset Browser"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "AssetBrowser::hideDialog();"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "256 107"; + extent = "512 554"; + minExtent = "383 274"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl(CreateAssetButton) { + text = "New"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "3 22"; + extent = "45 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ImportAssetButton) { + text = "Import"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "50 22"; + extent = "45 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiWindowCtrl(TagFilterWindow) { + text = "New Window"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + docking = "None"; + margin = "4 4 4 4"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "129 62"; + extent = "161 250"; + minExtent = "161 86"; + horizSizing = "windowRelative"; + vertSizing = "windowRelative"; + profile = "ToolsGuiToolbarWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "VisibilityLayerWindow"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "2 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 9"; + extent = "159 238"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl(TagFilterList) { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "-2"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "3 1"; + extent = "153 16"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "theVisOptionsList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiSplitContainer() { + orientation = "Vertical"; + splitterSize = "2"; + splitPoint = "149 100"; + fixedPanel = "None"; + fixedSize = "356"; + docking = "None"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "3 42"; + extent = "505 509"; + minExtent = "64 64"; + horizSizing = "relative"; + vertSizing = "height"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "147 509"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "Panel1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "147 31"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "inspectorStyleRolloutDarkProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Filters"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 0"; + extent = "30 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconNew.png"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "113 1"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.viewTagsFilter();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Show assets grouped and filtered via tags."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconList.png"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "130 1"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.viewListFilter();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Views assets via module-oriented list tree."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 17"; + extent = "147 493"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "147 493"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiEditorScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(AssetBrowserFilterTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + mouseDragging = "1"; + multipleSelections = "1"; + deleteObjectAllowed = "1"; + dragToItemAllowed = "1"; + clearAllOnSingleSelection = "1"; + showRoot = "1"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + showObjectIds = "1"; + showClassNames = "1"; + showObjectNames = "1"; + showInternalNames = "1"; + showClassNameForUnnamedObjects = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + position = "1 1"; + extent = "145 294"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTreeViewProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "filterTree"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "151 0"; + extent = "354 509"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "panel2"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 0"; + extent = "354 41"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "inspectorStyleRolloutDarkProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/new"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "42 22"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.createNewAsset();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Create New Asset"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "23 22"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.showDeleteDialog();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Delete Asset"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(AssetBrowserSearchFilter) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "\c2Filter..."; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "62 19"; + extent = "273 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "AssetBrowserSearchFilterText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(TagFilterButton) { + bitmap = "tools/gui/images/visible"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "4 19"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.toggleTagFilterPopup();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Assets"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 0"; + extent = "53 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "337 22"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.showDeleteDialog();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Delete Asset"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "1"; + position = "1 40"; + extent = "354 468"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl(AssetListPanel) { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "354 448"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiEditorScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "0"; + position = "1 1"; + extent = "352 254"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiModelessDialogProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "352 4"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiDynamicCtrlArrayControl() { + colCount = "3"; + colSize = "100"; + rowCount = "2"; + rowSize = "124"; + rowSpacing = "2"; + colSpacing = "2"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "1"; + dynamicSize = "1"; + padding = "0 0 0 0"; + position = "3 4"; + extent = "352 250"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "materialSelection"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiContainer() { + docking = "Bottom"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 448"; + extent = "354 20"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "materialPreviewControlContainer"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "242 491"; + extent = "53 19"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.selectAsset( AssetBrowser.selectedAsset );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "SelectButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "300 491"; + extent = "52 19"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.hideDialog();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/assetImport.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/assetImport.gui new file mode 100644 index 000000000..199ad91b8 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/assetImport.gui @@ -0,0 +1,613 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetImportCtrl) { + position = "0 0"; + extent = "1440 900"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(ImportAssetOptionsWindow) { + text = "Import Options"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "633 358"; + extent = "346 409"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "271 377"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetOptionsWindow.saveAssetOptions();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 26"; + extent = "326 344"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiVariableInspector(ImportOptionsList) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "309 64"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiWindowCtrl(ImportAssetConfigEditorWindow) { + text = "Import Options Config"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "562 251"; + extent = "376 503"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Configuration Name:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 26"; + extent = "100 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(AssetImportConfigName) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "113 25"; + extent = "250 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "301 471"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetConfigEditorWindow.saveAssetOptionsConfig();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 50"; + extent = "356 414"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiVariableInspector(ImportOptionsConfigList) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "339 64"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiWindowCtrl(ImportAssetWindow) { + text = "Import Assets"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "536 205"; + extent = "368 502"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "224 470"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetWindow.ImportAssets();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "292 470"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Target Module:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(ImportAssetModuleList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 27"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "342 27"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "Canvas.pushDialog(AssetBrowser_addModule);\nAssetBrowser_addModuleWindow.selectWindow();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "New Module"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Import Options Config:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 56"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(ImportAssetConfigList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "126 53"; + extent = "175 22"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "305 53"; + extent = "15 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetConfigEditorWindow.addNewConfig();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "New Config"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconInformation.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "325 53"; + extent = "15 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetConfigEditorWindow.editConfig();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Edit Config"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconDelete.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "346 53"; + extent = "15 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetConfigEditorWindow.deleteConfig();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Delete Config"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 82"; + extent = "348 381"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl(ImportingAssetList) { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "0"; + changeChildPosition = "1"; + position = "1 1"; + extent = "345 20"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/editAsset.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/editAsset.gui new file mode 100644 index 000000000..45d411f20 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/editAsset.gui @@ -0,0 +1,147 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_editAsset) { + position = "0 0"; + extent = "1920 1080"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_editAssetWindow) { + text = "Asset Properties"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(AssetBrowser_editAsset);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "710 375"; + extent = "500 329"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 21"; + extent = "498 283"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiInspector(AssetEditInspector) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "481 101"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiInspectorProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Save"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "402 305"; + extent = "45 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_editAsset.saveAsset();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "450 305"; + extent = "45 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_editAsset);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/editModule.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/editModule.gui new file mode 100644 index 000000000..90ff639dd --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/editModule.gui @@ -0,0 +1,147 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_editModule) { + position = "0 0"; + extent = "1920 1080"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_editModuleWindow) { + text = "Module Properties"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(AssetBrowser_editModule);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "710 375"; + extent = "500 329"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 21"; + extent = "498 283"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiInspector(ModuleEditInspector) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "481 101"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiInspectorProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Save"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "402 305"; + extent = "45 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_editModule.saveModule();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "450 305"; + extent = "45 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_editModule);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/newAsset.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/newAsset.gui new file mode 100644 index 000000000..09fcb997d --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/newAsset.gui @@ -0,0 +1,237 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_newAsset) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(AssetBrowser_newAssetWindow) { + text = "Create Asset"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(AssetBrowser_newAsset);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "328 140"; + extent = "368 450"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl(NewAssetCreateBtn) { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "227 419"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "CreateNewAsset();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "295 419"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_newAssetWindow.onClose();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Target Module:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(NewAssetModuleList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 27"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "AssetBrowserModuleList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(NewAssetModuleBtn) { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "342 27"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "Canvas.pushDialog(AssetBrowser_AddModule);\nAssetBrowser_addModuleWindow.selectWindow();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl(NewComponentAssetSettings) { + position = "12 120"; + extent = "344 107"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOn"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 56"; + extent = "354 357"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiVariableInspector(NewAssetPropertiesInspector) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "337 338"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/newComponentAsset.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/newComponentAsset.gui new file mode 100644 index 000000000..65896dccc --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/newComponentAsset.gui @@ -0,0 +1,434 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_newComponentAsset) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(AssetBrowser_newComponentAssetWindow) { + text = "Create Component"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(AssetBrowser_newComponentAsset);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "328 250"; + extent = "368 268"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Target Module:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 27"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "NewComponentModuleList"; + class = "AssetBrowserModuleList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "342 27"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "Canvas.pushDialog(AssetBrowser_AddModule);\nAssetBrowser_addModuleWindow.selectWindow();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "NewComponentModuleBtn"; + class = "NewAssetModuleBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Component Name:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 83"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(NewComponentName) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 83"; + extent = "203 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Parent Component:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 57"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(ParentComponentList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 54"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "NewAssetTypeList.onSelected();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(NewComponentFriendlyName) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 109"; + extent = "203 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Friendly Name:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 109"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(NewComponentGroup) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 134"; + extent = "203 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Component Group:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 134"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 159"; + extent = "203 64"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiMLTextEditCtrl(NewComponentDescription) { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + position = "1 0"; + extent = "201 64"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Description:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 159"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "224 240"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "createNewComponentAsset();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "292 240"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_newComponentAsset);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/selectModule.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/selectModule.gui new file mode 100644 index 000000000..a1c4293ab --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/selectModule.gui @@ -0,0 +1,144 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_SelectModule) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_SelectModuleWindow) { + text = "Select Module"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "362 334"; + extent = "299 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiPopUpMenuCtrlEx() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "39 34"; + extent = "217 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "AssetBrowserModuleList"; + internalName = "ModuleList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "260 32"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "SelectPackage_NewAssetModuleBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "88 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_SelectModule);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "220 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_addModule);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/selectPackage.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/selectPackage.gui new file mode 100644 index 000000000..055763d35 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/selectPackage.gui @@ -0,0 +1,144 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_SelectPackage) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_SelectPackageWindow) { + text = "Select Package"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "362 334"; + extent = "299 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiPopUpMenuCtrlEx() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "39 34"; + extent = "217 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "AssetBrowserPackageList"; + internalName = "PackageList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "260 32"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "SelectPackage_NewAssetPackageBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "88 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_SelectPackage);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "220 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_addPackage);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/main.cs b/Templates/BaseGame/game/tools/assetBrowser/main.cs new file mode 100644 index 000000000..32ae4682f --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/main.cs @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +if( !isObject( ToolsGuiDefaultNonModalProfile ) ) +new GuiControlProfile (ToolsGuiDefaultNonModalProfile : ToolsGuiDefaultProfile) +{ + modal = false; +}; + +function initializeAssetBrowser() +{ + echo(" % - Initializing Asset Browser"); + + exec("./guis/assetBrowser.gui"); + exec("./guis/addModuleWindow.gui"); + exec("./guis/gameObjectCreator.gui"); + exec("./guis/newAsset.gui"); + exec("./guis/newComponentAsset.gui"); + exec("./guis/editAsset.gui"); + exec("./guis/assetImport.gui"); + exec("./guis/selectModule.gui"); + exec("./guis/editModule.gui"); + + exec("./scripts/assetBrowser.cs"); + exec("./scripts/popupMenus.cs"); + exec("./scripts/addModuleWindow.cs"); + exec("./scripts/assetImport.cs"); + exec("./scripts/assetImportConfig.cs"); + exec("./scripts/gameObjectCreator.cs"); + exec("./scripts/newAsset.cs"); + exec("./scripts/editAsset.cs"); + exec("./scripts/editModule.cs"); + + exec("./scripts/fieldTypes.cs"); + + new ScriptObject( AssetBrowserPlugin ) + { + superClass = "EditorPlugin"; + }; + + Input::GetEventManager().subscribe( AssetBrowser, "BeginDropFiles" ); + Input::GetEventManager().subscribe( AssetBrowser, "DropFile" ); + Input::GetEventManager().subscribe( AssetBrowser, "EndDropFiles" ); + + AssetBrowser.buildPopupMenus(); +} + +function AssetBrowserPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the toolbar. + AssetBrowser.addToolbarButton(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.cs new file mode 100644 index 000000000..784ed7d63 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.cs @@ -0,0 +1,112 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +function AssetBrowser_addModuleWindow::onGainFirstResponder(%this) +{ + %this-->moduleName.setFirstResponder(); +} + +function AssetBrowser_addModuleWindow::close() +{ + Canvas.popDialog(AssetBrowser_addModule); + eval(AssetBrowser_addModuleWindow.callbackFunction); +} + +function AssetBrowser_addModuleWindow::CreateNewModule(%this) +{ + %newModuleName = %this-->moduleName.getText(); + + if(%newModuleName $= "") + return; + + echo("Creating a new Module named: " @ %newModuleName); + + %moduleFilePath = "data/" @ %newModuleName; + %moduleDefinitionFilePath = %moduleFilePath @ "/" @ %newModuleName @ ".module"; + %moduleScriptFilePath = %moduleFilePath @ "/" @ %newModuleName @ ".cs"; + + %newModule = new ModuleDefinition() + { + ModuleId = %newModuleName; + versionId = 1; + ScriptFile = %newModuleName @ ".cs"; + CreateFunction="onCreate"; + DestroyFunction="onDestroy"; + Group = "Game"; + + new DeclaredAssets() + { + Extension = "asset.taml"; + Recurse = true; + }; + }; + + TAMLWrite(%newModule, %moduleDefinitionFilePath); + + //Now generate the script file for it + %file = new FileObject(); + + if(%file.openForWrite(%moduleScriptFilePath)) + { + %file.writeline("function " @ %newModuleName @ "::onCreate(%this)\n{\n\n}\n"); + %file.writeline("function " @ %newModuleName @ "::onDestroy(%this)\n{\n\n}\n"); + + //todo, pre-write any event functions of interest + + %file.close(); + } + + //force a refresh of our modules list + ModuleDatabase.ignoreLoadedGroups(true); + ModuleDatabase.scanModules(); + %success = ModuleDatabase.loadExplicit(%newModuleName, 1); + ModuleDatabase.ignoreLoadedGroups(false); + + //force a reload of the Module lists + NewAssetModuleList.refresh(); + GameObjectModuleList.refresh(); + ImportAssetModuleList.refresh(); + + AssetBrowser.newModuleId = %newModuleName; + + Canvas.popDialog(AssetBrowser_addModule); + eval(AssetBrowser_addModuleWindow.callbackFunction); +} + +function AssetBrowserModuleList::onWake(%this) +{ + %this.refresh(); +} + +function AssetBrowserModuleList::refresh(%this) +{ + %this.clear(); + + //First, get our list of modules + %moduleList = ModuleDatabase.findModules(); + + %count = getWordCount(%moduleList); + for(%i=0; %i < %count; %i++) + { + %moduleName = getWord(%moduleList, %i); + %this.add(%moduleName.ModuleId, %i); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/addPackageWindow.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/addPackageWindow.cs new file mode 100644 index 000000000..90d999b8e --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/addPackageWindow.cs @@ -0,0 +1,110 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +function AssetBrowser_addPackageWindow::onGainFirstResponder(%this) +{ + %this-->packageName.setFirstResponder(); +} + +function AssetBrowser_addPackageWindow::close() +{ + Canvas.popDialog(AssetBrowser_addPackage); + eval(AssetBrowser_addPackageWindow.callbackFunction); +} + +function AssetBrowser_addPackageWindow::CreateNewPackage(%this) +{ + %newPackageName = %this-->packageName.getText(); + + if(%newPackageName $= "") + return; + + echo("Creating a new package named: " @ %newPackageName); + + %moduleFilePath = "data/" @ %newPackageName; + %moduleDefinitionFilePath = %moduleFilePath @ "/" @ %newPackageName @ ".module"; + %moduleScriptFilePath = %moduleFilePath @ "/" @ %newPackageName @ ".cs"; + + %newPackage = new ModuleDefinition() + { + ModuleId = %newPackageName; + versionId = 1; + ScriptFile = %newPackageName @ ".cs"; + CreateFunction="onCreate"; + DestroyFunction="onDestroy"; + Group = "Game"; + + new DeclaredAssets() + { + Extension = "asset.taml"; + Recurse = true; + }; + }; + + TAMLWrite(%newPackage, %moduleDefinitionFilePath); + + //Now generate the script file for it + %file = new FileObject(); + + if(%file.openForWrite(%moduleScriptFilePath)) + { + %file.writeline("function " @ %newPackageName @ "::onCreate(%this)\n{\n\n}\n"); + %file.writeline("function " @ %newPackageName @ "::onDestroy(%this)\n{\n\n}\n"); + + //todo, pre-write any event functions of interest + + %file.close(); + } + + //force a refresh of our modules list + ModuleDatabase.ignoreLoadedGroups(true); + ModuleDatabase.scanModules(); + %success = ModuleDatabase.loadExplicit(%newPackageName, 1); + ModuleDatabase.ignoreLoadedGroups(false); + + //force a reload of the package lists + NewAssetPackageList.refresh(); + GameObjectPackageList.refresh(); + ImportAssetPackageList.refresh(); + + Canvas.popDialog(AssetBrowser_addPackage); + eval(AssetBrowser_addPackageWindow.callbackFunction); +} + +function AssetBrowserPackageList::onWake(%this) +{ + %this.refresh(); +} + +function AssetBrowserPackageList::refresh(%this) +{ + %this.clear(); + + //First, get our list of modules + %moduleList = ModuleDatabase.findModules(); + + %count = getWordCount(%moduleList); + for(%i=0; %i < %count; %i++) + { + %moduleName = getWord(%moduleList, %i); + %this.add(%moduleName.ModuleId, %i); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs new file mode 100644 index 000000000..0979f219e --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs @@ -0,0 +1,1304 @@ + +new SimGroup(AssetBrowserPreviewCache); + +//AssetBrowser.addToolbarButton +function AssetBrowser::addToolbarButton(%this) +{ + %filename = expandFilename("tools/gui/images/iconOpen"); + %button = new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = AssetBrowserBtn; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "180 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "AssetBrowser.ShowDialog();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Asset Browser"; + hovertime = "750"; + bitmap = %filename; + bitmapMode = "Centered"; + buttonType = "PushButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + ToolsToolbarArray.add(%button); + EWToolsToolbar.setExtent((25 + 8) * (ToolsToolbarArray.getCount()) + 12 SPC "33"); +} +// +function AssetBrowser::onAdd(%this) +{ + %this.isReImportingAsset = false; +} + +function AssetBrowser::onWake(%this) +{ + %this.importAssetNewListArray = new ArrayObject(); + %this.importAssetUnprocessedListArray = new ArrayObject(); + %this.importAssetFinalListArray = new ArrayObject(); +} + +//Drag-Drop functionality +function AssetBrowser::selectAsset( %this, %asset ) +{ + if(AssetBrowser.selectCallback !$= "") + { + // The callback function should be ready to intake the returned material + //eval("materialEd_previewMaterial." @ %propertyField @ " = " @ %value @ ";"); + if( AssetBrowser.returnType $= "name" ) + { + eval( "" @ AssetBrowser.selectCallback @ "(" @ %name @ ");"); + } + else + { + %command = "" @ AssetBrowser.selectCallback @ "(\"" @ %asset @ "\");"; + eval(%command); + } + } + else + { + //try just setting the asset + %this.changeAsset(); + } + + Inspector.refresh(); + + AssetBrowser.hideDialog(); +} + +function AssetBrowser::showDialog( %this, %AssetTypeFilter, %selectCallback, %targetObj, %fieldName, %returnType) +{ + // Set the select callback + AssetBrowser.selectCallback = %selectCallback; + AssetBrowser.returnType = %returnType; + AssetBrowser.assetTypeFilter = %AssetTypeFilter; + AssetBrowser.fieldTargetObject = %targetObj; + AssetBrowser.fieldTargetName = %fieldName; + + Canvas.add(AssetBrowser); + AssetBrowser.setVisible(1); + AssetBrowserWindow.setVisible(1); + AssetBrowserWindow.selectWindow(); + + if(%selectCallback $= "") + { + //we're not in selection mode, so just hide the select button + %this-->SelectButton.setHidden(true); + } + else + { + %this-->SelectButton.setHidden(false); + } + + //AssetBrowser_importAssetWindow.setVisible(0); + //AssetBrowser_importAssetConfigWindow.setVisible(0); + AssetBrowser.loadFilters(); +} + +function AssetBrowser::hideDialog( %this ) +{ + AssetBrowser.setVisible(1); + AssetBrowserWindow.setVisible(1); + Canvas.popDialog(AssetBrowser_addModule); + Canvas.popDialog(ImportAssetWindow); + + Canvas.popDialog(AssetBrowser); +} + +function AssetBrowser::buildPreviewArray( %this, %asset, %moduleName ) +{ + %assetDesc = AssetDatabase.acquireAsset(%asset); + %assetName = AssetDatabase.getAssetName(%asset); + %previewImage = "core/art/warnmat"; + + AssetPreviewArray.empty(); + + // it may seem goofy why the checkbox can't be instanciated inside the container + // reason being its because we need to store the checkbox ctrl in order to make changes + // on it later in the function. + + %previewSize = "80 80"; + %previewBounds = 20; + + %assetType = AssetDatabase.getAssetType(%asset); + + %container = new GuiControl(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = %previewSize.x + %previewBounds SPC %previewSize.y + %previewBounds + 24; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + assetName = %assetName; + moduleName = %moduleName; + assetType = %assetType; + }; + + %tooltip = %assetName; + + if(%assetType $= "ShapeAsset") + { + %previewButton = new GuiObjectView() + { + className = "AssetPreviewControl"; + internalName = %matName; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiDefaultProfile"; + position = "7 4"; + extent = %previewSize; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + renderMissionArea = "0"; + GizmoProfile = "GlobalGizmoProfile"; + cameraZRot = "0"; + forceFOV = "0"; + gridColor = "0 0 0 0"; + renderNodes = "0"; + renderObjBox = "0"; + renderMounts = "0"; + renderColMeshes = "0"; + selectedNode = "-1"; + sunDiffuse = "255 255 255 255"; + sunAmbient = "180 180 180 255"; + timeScale = "1.0"; + fixedDetail = "0"; + orbitNode = "0"; + + new GuiBitmapButtonCtrl() + { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "0 0"; + extent = %previewSize; + Variable = ""; + buttonType = "ToggleButton"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + groupNum = "0"; + text = ""; + }; + }; + + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + %name = AssetDatabase.getAssetName(%assetId); + + if(%name $= %assetName) + { + %asset = AssetDatabase.acquireAsset(%assetId); + + %previewButton.setModel(%asset.fileName); + //%previewButton.refreshShape(); + //%previewButton.currentDL = 0; + //%previewButton.fitToShape(); + + break; + } + } + } + else + { + if(%assetType $= "ComponentAsset") + { + %assetPath = "data/" @ %moduleName @ "/components/" @ %assetName @ ".cs"; + %doubleClickCommand = "EditorOpenFileInTorsion( "@%assetPath@", 0 );"; + + %previewImage = "tools/assetBrowser/art/componentIcon"; + + %assetFriendlyName = %assetDesc.friendlyName; + %assetDesc = %assetDesc.description; + %tooltip = %assetFriendlyName @ "\n" @ %assetDesc; + } + else if(%assetType $= "GameObjectAsset") + { + %assetPath = "data/" @ %moduleName @ "/gameObjects/" @ %assetName @ ".cs"; + %doubleClickCommand = "EditorOpenFileInTorsion( "@%assetPath@", 0 );"; + + %previewImage = "tools/assetBrowser/art/gameObjectIcon"; + + %tooltip = %assetDesc.gameObjectName; + } + else if(%assetType $= "ImageAsset") + { + //nab the image and use it for the preview + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + %name = AssetDatabase.getAssetName(%assetId); + + if(%name $= %assetName) + { + %asset = AssetDatabase.acquireAsset(%assetId); + %previewImage = %asset.imageFile; + break; + } + } + } + else if(%assetType $= "StateMachineAsset") + { + %previewImage = "tools/assetBrowser/art/stateMachineIcon"; + } + else if(%assetType $= "SoundAsset") + { + %previewImage = "tools/assetBrowser/art/soundIcon"; + } + else if(%assetType $= "LevelAsset") + { + %previewImage = "tools/assetBrowser/art/levelIcon"; + } + else if(%assetType $= "PostEffectAsset") + { + %previewImage = "tools/assetBrowser/art/postEffectIcon"; + } + else if(%assetType $= "GUIAsset") + { + %previewImage = "tools/assetBrowser/art/guiIcon"; + } + else if(%assetType $= "ScriptAsset") + { + if(%assetDesc.isServerSide) + %previewImage = "tools/assetBrowser/art/serverScriptIcon"; + else + %previewImage = "tools/assetBrowser/art/clientScriptIcon"; + } + else if(%assetType $= "MaterialAsset") + { + %previewImage = ""; + //nab the image and use it for the preview + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + %name = AssetDatabase.getAssetName(%assetId); + + if(%name $= %assetName) + { + %asset = AssetDatabase.acquireAsset(%assetId); + %previewImage = %asset.materialDefinitionName.diffuseMap[0]; + break; + } + } + + if(%previewImage $= "") + %previewImage = "tools/assetBrowser/art/materialIcon"; + } + if(%assetType $= "ShapeAnimationAsset") + { + %previewImage = "tools/assetBrowser/art/animationIcon"; + } + + %previewButton = new GuiBitmapButtonCtrl() + { + className = "AssetPreviewControl"; + internalName = %assetName; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "10 4"; + extent = %previewSize; + buttonType = "PushButton"; + bitmap = %previewImage; + Command = ""; + text = ""; + useStates = false; + + new GuiBitmapButtonCtrl() + { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "0 0"; + extent = %previewSize; + Variable = ""; + buttonType = "toggleButton"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + groupNum = "0"; + text = ""; + }; + }; + } + + %previewBorder = new GuiButtonCtrl(){ + class = "AssetPreviewButton"; + internalName = %assetName@"Border"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiThumbHighlightButtonProfile"; + position = "0 0"; + extent = %previewSize.x + %previewBounds SPC %previewSize.y + 24; + Variable = ""; + buttonType = "radioButton"; + tooltip = %tooltip; + Command = "AssetBrowser.updateSelection( $ThisControl.getParent().assetName, $ThisControl.getParent().moduleName );"; + altCommand = %doubleClickCommand; + groupNum = "0"; + useMouseEvents = true; + text = ""; + icon = %previewImage; + }; + + %previewNameCtrl = new GuiTextEditCtrl(){ + position = 0 SPC %previewSize.y + %previewBounds - 16; + profile = ToolsGuiTextEditCenterProfile; + extent = %previewSize.x + %previewBounds SPC 16; + text = %assetName; + originalAssetName = %assetName; //special internal field used in renaming assets + internalName = "AssetNameLabel"; + class = "AssetNameField"; + active = false; + }; + + %container.add(%previewButton); + %container.add(%previewBorder); + %container.add(%previewNameCtrl); + + // add to the gui control array + AssetBrowser-->materialSelection.add(%container); + + // add to the array object for reference later + AssetPreviewArray.add( %previewButton, %previewImage ); +} + +function AssetBrowser::loadImages( %this, %materialNum ) +{ + // this will save us from spinning our wheels in case we don't exist + /*if( !AssetBrowser.visible ) + return; + + // this schedule is here to dynamically load images + %previewButton = AssetPreviewArray.getKey(%materialNum); + %previewImage = AssetPreviewArray.getValue(%materialNum); + + if(%previewButton.getClassName() !$= "GuiObjectView") + { + %previewButton.setBitmap(%previewImage); + %previewButton.setText(""); + } + + %materialNum++; + + /*if( %materialNum < AssetPreviewArray.count() ) + { + %tempSchedule = %this.schedule(64, "loadImages", %materialNum); + MatEdScheduleArray.add( %tempSchedule, %materialNum ); + }*/ +} + +function AssetBrowser::loadFilters( %this ) +{ + AssetBrowser-->filterTree.clear(); + + AssetBrowser-->filterTree.buildIconTable(":tools/classIcons/prefab"); + + AssetBrowser-->filterTree.insertItem(0, "Assets"); + + //First, build our our list of active modules + %modulesList = ModuleDatabase.findModules(true); + + for(%i=0; %i < getWordCount(%modulesList); %i++) + { + %moduleName = getWord(%modulesList, %i).ModuleId; + + %moduleItemId = AssetBrowser-->filterTree.findItemByName(%moduleName); + + if(%moduleItemId == 0) + %moduleItemId = AssetBrowser-->filterTree.insertItem(1, %moduleName, "", "", 1, 1); + } + + //Next, go through and list the asset categories + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %moduleName = %module.moduleId; + + //These are core, native-level components, so we're not going to be messing with this module at all, skip it + if(%moduleName $= "CoreComponentsModule") + continue; + + //first, see if this module Module is listed already + %moduleItemId = AssetBrowser-->filterTree.findItemByName(%moduleName); + + if(%moduleItemId == 0) + %moduleItemId = AssetBrowser-->filterTree.insertItem(1, %moduleName, "", "", 1, 1); + + %assetType = AssetDatabase.getAssetCategory(%assetId); + + if(%assetType $= "") + { + %assetType = AssetDatabase.getAssetType(%assetId); + if(%assetType $= "") + %assetType = "Misc"; + } + + if(AssetBrowser.assetTypeFilter !$= "" && AssetBrowser.assetTypeFilter !$= %assetType) + continue; + + %assetTypeId = AssetBrowser-->filterTree.findChildItemByName(%moduleItemId, %assetType); + + if(%assetTypeId == 0) + %assetTypeId = AssetBrowser-->filterTree.insertItem(%moduleItemId, %assetType); + } + + AssetBrowser-->filterTree.buildVisibleTree(true); + + //special handling for selections + if(AssetBrowser.newModuleId !$= "") + { + AssetBrowser-->filterTree.clearSelection(); + %newModuleItem = AssetBrowser-->filterTree.findItemByName(AssetBrowser.newModuleId); + AssetBrowser-->filterTree.selectItem(%newModuleItem); + AssetBrowser.newModuleId = ""; + } + + %selectedItem = AssetBrowser-->filterTree.getSelectedItem(); + AssetBrowser-->filterTree.scrollVisibleByObjectId(%selectedItem); +} + +// create category and update current material if there is one +function AssetBrowser::createFilter( %this, %filter ) +{ + if( %filter $= %existingFilters ) + { + MessageBoxOK( "Error", "Can not create blank filter."); + return; + } + + for( %i = AssetBrowser.staticFilterObjects; %i < AssetBrowser-->filterArray.getCount() ; %i++ ) + { + %existingFilters = AssetBrowser-->filterArray.getObject(%i).getObject(0).filter; + if( %filter $= %existingFilters ) + { + MessageBoxOK( "Error", "Can not create two filters of the same name."); + return; + } + } + %container = new GuiControl(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiCheckBoxCtrl(){ + Profile = "ToolsGuiCheckBoxListProfile"; + position = "5 1"; + Extent = "118 18"; + Command = ""; + groupNum = "0"; + buttonType = "ToggleButton"; + text = %filter @ " ( " @ MaterialFilterAllArray.countKey(%filter) @ " )"; + filter = %filter; + Command = "AssetBrowser.preloadFilter();"; + }; + }; + + AssetBrowser-->filterArray.add( %container ); + + // if selection exists, lets reselect it to refresh it + if( isObject(AssetBrowser.selectedMaterial) ) + AssetBrowser.updateSelection( AssetBrowser.selectedMaterial, AssetBrowser.selectedPreviewImagePath ); + + // material category text field to blank + AssetBrowser_addFilterWindow-->tagName.setText(""); +} + +function AssetBrowser::updateSelection( %this, %asset, %moduleName ) +{ + // the material selector will visually update per material information + // after we move away from the material. eg: if we remove a field from the material, + // the empty checkbox will still be there until you move fro and to the material again + + %isAssetBorder = 0; + eval("%isAssetBorder = isObject(AssetBrowser-->"@%asset@"Border);"); + if( %isAssetBorder ) + { + eval( "AssetBrowser-->"@%asset@"Border.setStateOn(1);"); + } + + %isAssetBorderPrevious = 0; + eval("%isAssetBorderPrevious = isObject(AssetBrowser-->"@%this.prevSelectedMaterialHL@"Border);"); + if( %isAssetBorderPrevious ) + { + eval( "AssetBrowser-->"@%this.prevSelectedMaterialHL@"Border.setStateOn(0);"); + } + + AssetBrowser.selectedMaterial = %asset; + AssetBrowser.selectedAsset = %moduleName@":"@%asset; + AssetBrowser.selectedAssetDef = AssetDatabase.acquireAsset(AssetBrowser.selectedAsset); + //AssetBrowser.selectedPreviewImagePath = %previewImagePath; + + %this.prevSelectedMaterialHL = %asset; +} + +// +//needs to be deleted with the persistence manager and needs to be blanked out of the matmanager +//also need to update instances... i guess which is the tricky part.... +function AssetBrowser::showDeleteDialog( %this ) +{ + %material = AssetBrowser.selectedMaterial; + %secondFilter = "MaterialFilterMappedArray"; + %secondFilterName = "Mapped"; + + for( %i = 0; %i < MaterialFilterUnmappedArray.count(); %i++ ) + { + if( MaterialFilterUnmappedArray.getValue(%i) $= %material ) + { + %secondFilter = "MaterialFilterUnmappedArray"; + %secondFilterName = "Unmapped"; + break; + } + } + + if( isObject( %material ) ) + { + MessageBoxYesNoCancel("Delete Material?", + "Are you sure you want to delete

" @ %material.getName() @ "

Material deletion won't take affect until the engine is quit.", + "AssetBrowser.deleteMaterial( " @ %material @ ", " @ %secondFilter @ ", " @ %secondFilterName @" );", + "", + "" ); + } +} + +function AssetBrowser::deleteMaterial( %this, %materialName, %secondFilter, %secondFilterName ) +{ + if( !isObject( %materialName ) ) + return; + + for( %i = 0; %i <= MaterialFilterAllArray.countValue( %materialName ); %i++) + { + %index = MaterialFilterAllArray.getIndexFromValue( %materialName ); + MaterialFilterAllArray.erase( %index ); + } + MaterialFilterAllArrayCheckbox.setText("All ( " @ MaterialFilterAllArray.count() - 1 @ " ) "); + + %checkbox = %secondFilter @ "Checkbox"; + for( %k = 0; %k <= %secondFilter.countValue( %materialName ); %k++) + { + %index = %secondFilter.getIndexFromValue( %materialName ); + %secondFilter.erase( %index ); + } + %checkbox.setText( %secondFilterName @ " ( " @ %secondFilter.count() - 1 @ " ) "); + + for( %i = 0; %materialName.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %materialTag = %materialName.getFieldValue("materialTag" @ %i); + + for( %j = AssetBrowser.staticFilterObjects; %j < AssetBrowser-->filterArray.getCount() ; %j++ ) + { + if( %materialTag $= AssetBrowser-->filterArray.getObject(%j).getObject(0).filter ) + { + %count = getWord( AssetBrowser-->filterArray.getObject(%j).getObject(0).getText(), 2 ); + %count--; + AssetBrowser-->filterArray.getObject(%j).getObject(0).setText( %materialTag @ " ( "@ %count @ " )"); + } + } + + } + + UnlistedMaterials.add( "unlistedMaterials", %materialName ); + + if( %materialName.getFilename() !$= "" && + %materialName.getFilename() !$= "tools/gui/AssetBrowser.ed.gui" && + %materialName.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs" ) + { + AssetBrowserPerMan.removeObjectFromFile(%materialName); + AssetBrowserPerMan.saveDirty(); + } + + AssetBrowser.preloadFilter(); +} + +function AssetBrowser::thumbnailCountUpdate(%this) +{ + $Pref::AssetBrowser::ThumbnailCountIndex = AssetBrowser-->materialPreviewCountPopup.getSelected(); + AssetBrowser.LoadFilter( AssetBrowser.currentFilter, AssetBrowser.currentStaticFilter ); +} + +function AssetBrowser::toggleTagFilterPopup(%this) +{ + if(TagFilterWindow.visible) + TagFilterWindow.visible = false; + else + TagFilterWindow.visible = true; + + return; + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %moduleName = %module.moduleId; + + //check that we don't re-add it + %moduleItemId = AssetBrowser-->filterTree.findItemByName(%moduleName); + + if(%moduleItemId == -1 || %moduleItemId == 0) + %moduleItemId = AssetBrowser-->filterTree.insertItem(1, %module.moduleId, "", "", 1, 1); + + //now, add the asset's category + %assetType = AssetDatabase.getAssetCategory(%assetId); + + %checkBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = (%textLength * 4) @ " 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = %var; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + Command = %cmd; + }; + + TagFilterList.add(%checkBox); + } +} + +function AssetBrowser::changeAsset(%this) +{ + //alright, we've selectd an asset for a field, so time to set it! + %cmd = %this.fieldTargetObject @ "." @ %this.fieldTargetName @ "=\"" @ %this.selectedAsset @ "\";"; + echo("Changing asset via the " @ %cmd @ " command"); + eval(%cmd); +} + +function AssetBrowser::reImportAsset(%this) +{ + //Find out what type it is + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %assetType = AssetDatabase.getAssetType(EditAssetPopup.assetId); + + if(%assetType $= "ShapeAsset" || %assetType $= "ImageAsset" || %assetType $= "SoundAsset") + { + AssetBrowser.isAssetReImport = true; + AssetBrowser.reImportingAssetId = EditAssetPopup.assetId; + + AssetBrowser.onBeginDropFiles(); + AssetBrowser.onDropFile(%assetDef.originalFilePath); + AssetBrowser.onEndDropFiles(); + + %module = AssetDatabase.getAssetModule(EditAssetPopup.assetId); + + //get the selected module data + ImportAssetModuleList.setText(%module.ModuleId); + } +} + +//------------------------------------------------------------------------------ +function AssetPreviewButton::onRightClick(%this) +{ + AssetBrowser.selectedAssetPreview = %this.getParent(); + EditAssetPopup.assetId = %this.getParent().moduleName @ ":" @ %this.getParent().assetName; + %assetType = %this.getParent().assetType; + + //Do some enabling/disabling of options depending on asset type + EditAssetPopup.enableItem(0, true); + EditAssetPopup.enableItem(7, true); + + //Is it an editable type? + if(%assetType $= "ImageAsset" || %assetType $= "GameObjectAsset" || %assetType $= "SoundAsset") + { + EditAssetPopup.enableItem(0, false); + } + + //Is it an importable type? + if(%assetType $= "GameObjectAsset" || %assetType $= "ComponentAsset" || %assetType $= "GUIAsset" || %assetType $= "LevelAsset" + || %assetType $= "MaterialAsset" || %assetType $= "ParticleAsset" || %assetType $= "PostEffectAsset" || %assetType $= "ScriptAsset" + || %assetType $= "StateMachineAsset") + { + EditAssetPopup.enableItem(7, false); + } + + EditAssetPopup.showPopup(Canvas); +} + +function AssetListPanel::onRightMouseDown(%this) +{ + AddNewAssetPopup.showPopup(Canvas); +} + +//------------------------------------------------------------------------------ +function AssetBrowser::refreshPreviews(%this) +{ + AssetBrowserFilterTree.onSelect(AssetBrowser.selectedItem); +} + +function AssetBrowserFilterTree::onSelect(%this, %itemId) +{ + if(%itemId == 1) + //can't select root + return; + + //Make sure we have an actual module selected! + %parentId = %this.getParentItem(%itemId); + + if(%parentId != 1) + AssetBrowser.selectedModule = %this.getItemText(%parentId);//looks like we have one of the categories selected, not the module. Nab the parent so we have the correct thing! + else + AssetBrowser.selectedModule = %this.getItemText(%itemId); + + AssetBrowser.selectedItem = %itemId; + + //alright, we have a module or sub-filter selected, so now build our asset list based on that filter! + echo("Asset Browser Filter Tree selected filter #:" @ %itemId); + + // manage schedule array properly + if(!isObject(MatEdScheduleArray)) + new ArrayObject(MatEdScheduleArray); + + // if we select another list... delete all schedules that were created by + // previous load + for( %i = 0; %i < MatEdScheduleArray.count(); %i++ ) + cancel(MatEdScheduleArray.getKey(%i)); + + // we have to empty out the list; so when we create new schedules, these dont linger + MatEdScheduleArray.empty(); + + // manage preview array + if(!isObject(AssetPreviewArray)) + new ArrayObject(AssetPreviewArray); + + // we have to empty out the list; so when we create new guicontrols, these dont linger + AssetPreviewArray.empty(); + AssetBrowser-->materialSelection.deleteAllObjects(); + //AssetBrowser-->materialPreviewPagesStack.deleteAllObjects(); + + %assetArray = new ArrayObject(); + + //First, Query for our assets + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + //module name per our selected filter: + %moduleItemId = %this.getParentItem(%itemId); + + //check if we've selected a Module + if(%moduleItemId == 1) + { + %FilterModuleName = %this.getItemText(%itemId); + } + else + { + %FilterModuleName = %this.getItemText(%moduleItemId); + } + + //now, we'll iterate through, and find the assets that are in this module, and this category + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %moduleName = %module.moduleId; + + if(%FilterModuleName $= %moduleName) + { + //it's good, so test that the category is right! + %assetType = AssetDatabase.getAssetCategory(%assetId); + if(%assetType $= "") + { + %assetType = AssetDatabase.getAssetType(%assetId); + } + + if(%this.getItemText(%itemId) $= %assetType || (%assetType $= "" && %this.getItemText(%itemId) $= "Misc") + || %moduleItemId == 1) + { + //stop adding after previewsPerPage is hit + %assetName = AssetDatabase.getAssetName(%assetId); + + %searchText = AssetBrowserSearchFilter.getText(); + if(%searchText !$= "\c2Filter...") + { + if(strstr(strlwr(%assetName), strlwr(%searchText)) != -1) + %assetArray.add( %moduleName, %assetId); + } + else + { + //got it. + %assetArray.add( %moduleName, %assetId ); + } + } + } + } + + AssetBrowser.currentPreviewPage = 0; + AssetBrowser.totalPages = 1; + + for(%i=0; %i < %assetArray.count(); %i++) + AssetBrowser.buildPreviewArray( %assetArray.getValue(%i), %assetArray.getKey(%i) ); + + AssetBrowser.loadImages( 0 ); +} + +function AssetBrowserFilterTree::onRightMouseDown(%this, %itemId) +{ + if( %this.getSelectedItemsCount() > 0 && %itemId != 1) + { + //AddNewAssetPopup.showPopup(Canvas); + + //We have something clicked, so figure out if it's a sub-filter or a module filter, then push the correct + //popup menu + if(%this.getParentItem(%itemId) == 1) + { + //yep, module, push the all-inclusive popup + EditModulePopup.showPopup(Canvas); + //also set the module value for creation info + AssetBrowser.selectedModule = %this.getItemText(%itemId); + } + else + { + //get the parent, and thus our module + %moduleId = %this.getParentItem(%itemId); + + //set the module value for creation info + AssetBrowser.selectedModule = %this.getItemText(%moduleId); + + if(%this.getItemText(%itemId) $= "ComponentAsset") + { + AddNewComponentAssetPopup.showPopup(Canvas); + //Canvas.popDialog(AssetBrowser_newComponentAsset); + //AssetBrowser_newComponentAsset-->AssetBrowserModuleList.setText(AssetBrowser.selectedModule); + } + else + { + + } + } + } + else if( %this.getSelectedItemsCount() > 0 && %itemId == 1) + { + AddNewModulePopup.showPopup(Canvas); + } +} + +// +// +function AssetBrowserSearchFilterText::onWake( %this ) +{ + /*%filter = %this.treeView.getFilterText(); + if( %filter $= "" ) + %this.setText( "\c2Filter..." ); + else + %this.setText( %filter );*/ +} + +//------------------------------------------------------------------------------ + +function AssetBrowserSearchFilterText::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} + +//--------------------------------------------------------------------------------------------- + +// When Enter is pressed in the filter text control, pass along the text of the control +// as the treeview's filter. +function AssetBrowserSearchFilterText::onReturn( %this ) +{ + %text = %this.getText(); + if( %text $= "" ) + %this.reset(); + else + { + //%this.treeView.setFilterText( %text ); + %curItem = AssetBrowserFilterTree.getSelectedItem(); + AssetBrowserFilterTree.onSelect(%curItem); + } +} + +//--------------------------------------------------------------------------------------------- + +function AssetBrowserSearchFilterText::reset( %this ) +{ + %this.setText( "\c2Filter..." ); + //%this.treeView.clearFilterText(); + %curItem = AssetBrowserFilterTree.getSelectedItem(); + AssetBrowserFilterTree.onSelect(%curItem); +} + +//--------------------------------------------------------------------------------------------- + +function AssetBrowserSearchFilterText::onClick( %this ) +{ + %this.textCtrl.reset(); +} + +// +// +// +function AssetBrowser::reloadModules(%this) +{ + ModuleDatabase.unloadGroup("Game"); + + %modulesList = ModuleDatabase.findModules(); + + %count = getWordCount(%modulesList); + + for(%i=0; %i < %count; %i++) + { + %moduleId = getWord(%modulesList, %i).ModuleId; + ModuleDatabase.unloadExplicit(%moduleId); + } + + ModuleDatabase.scanModules(); + + %modulesList = ModuleDatabase.findModules(); + + %count = getWordCount(%modulesList); + + for(%i=0; %i < %count; %i++) + { + %moduleId = getWord(%modulesList, %i).ModuleId; + ModuleDatabase.loadExplicit(%moduleId); + } + + //ModuleDatabase.loadGroup("Game"); +} +// + +function AssetPreviewButton::onMouseDragged(%this) +{ + %payload = new GuiBitmapButtonCtrl(); + %payload.assignFieldsFrom( %this ); + %payload.className = "AssetPreviewControl"; + %payload.position = "0 0"; + %payload.dragSourceControl = %this; + %payload.bitmap = %this.icon; + %payload.extent.x /= 2; + %payload.extent.y /= 2; + + %xOffset = getWord( %payload.extent, 0 ) / 2; + %yOffset = getWord( %payload.extent, 1 ) / 2; + + // Compute the initial position of the GuiDragAndDrop control on the cavas based on the current + // mouse cursor position. + + %cursorpos = Canvas.getCursorPos(); + %xPos = getWord( %cursorpos, 0 ) - %xOffset; + %yPos = getWord( %cursorpos, 1 ) - %yOffset; + + if(!isObject(EditorDragAndDropLayer)) + { + new GuiControl(EditorDragAndDropLayer) + { + position = "0 0"; + extent = Canvas.extent; + }; + } + + // Create the drag control. + %ctrl = new GuiDragAndDropControl() + { + canSaveDynamicFields = "0"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %xPos SPC %yPos; + extent = %payload.extent; + MinExtent = "4 4"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + // Let the GuiDragAndDropControl delete itself on mouse-up. When the drag is aborted, + // this not only deletes the drag control but also our payload. + deleteOnMouseUp = true; + + useWholeCanvas = true; + + // To differentiate drags, use the namespace hierarchy to classify them. + // This will allow a color swatch drag to tell itself apart from a file drag, for example. + class = "AssetPreviewControlType_AssetDrop"; + }; + + // Add the temporary color swatch to the drag control as the payload. + %ctrl.add( %payload ); + + // Start drag by adding the drag control to the canvas and then calling startDragging(). + //Canvas.getContent().add( %ctrl ); + EditorDragAndDropLayer.add(%ctrl); + Canvas.pushDialog(EditorDragAndDropLayer); + + %ctrl.startDragging( %xOffset, %yOffset ); +} + +function AssetPreviewButton::onControlDragCancelled(%this) +{ + Canvas.popDialog(EditorDragAndDropLayer); +} + +function AssetPreviewButton::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + // If dropped on same button whence we came from, + // do nothing. + + if( %payload.dragSourceControl == %this ) + return; + + // If a swatch button control is dropped onto this control, + // copy it's color. + + if( %payload.isMemberOfClass( "AssetPreviewButton" ) ) + { + // If the swatch button is part of a color-type inspector field, + // remember the inspector field so we can later set the color + // through it. + + if( %this.parentGroup.isMemberOfClass( "GuiInspectorTypeColorI" ) ) + %this.parentGroup.apply( ColorFloatToInt( %payload.color ) ); + else if( %this.parentGroup.isMemberOfClass( "GuiInspectorTypeColorF" ) ) + %this.parentGroup.apply( %payload.color ); + else + %this.setColor( %payload.color ); + } +} + +function EWorldEditor::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + // If dropped on same button whence we came from, + // do nothing. + + if( %payload.dragSourceControl == %this ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + + %pos = EWCreatorWindow.getCreateObjectPosition(); //LocalClientConnection.camera.position; + %module = %payload.dragSourceControl.parentGroup.moduleName; + %asset = %payload.dragSourceControl.parentGroup.assetName; + + if(%assetType $= "ImageAsset") + { + echo("DROPPED AN IMAGE ON THE EDITOR WINDOW!"); + } + else if(%assetType $= "ShapeAsset") + { + echo("DROPPED A SHAPE ON THE EDITOR WINDOW!"); + + %newEntity = new Entity() + { + position = %pos; + + new MeshComponent() + { + MeshAsset = %module @ ":" @ %asset; + }; + + //new CollisionComponent(){}; + }; + + MissionGroup.add(%newEntity); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%newEntity); + } + else if(%assetType $= "MaterialAsset") + { + echo("DROPPED A MATERIAL ON THE EDITOR WINDOW!"); + } + else if(%assetType $= "GameObjectAsset") + { + echo("DROPPED A GAME OBJECT ON THE EDITOR WINDOW!"); + + %GO = spawnGameObject(%asset, true); + + %pos = EWCreatorWindow.getCreateObjectPosition(); //LocalClientConnection.camera.position; + + %GO.position = %pos; + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%GO); + } + else if(%assetType $= "ComponentAsset") + { + %newEntity = new Entity() + { + position = %pos; + }; + + %assetDef = AssetDatabase.acquireAsset(%module @ ":" @ %asset); + + if(%assetDef.componentClass $= "Component") + eval("$tmpVar = new " @ %assetDef.componentClass @ "() { class = " @ %assetDef.componentName @ "; }; %newEntity.add($tmpVar);"); + else + eval("$tmpVar = new " @ %assetDef.componentClass @ "() {}; %newEntity.add($tmpVar);"); + + MissionGroup.add(%newEntity); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%newEntity); + } + else if(%assetType $= "ScriptAsset") //do we want to do it this way? + { + %newEntity = new Entity() + { + position = %pos; + class = %asset; + }; + + MissionGroup.add(%newEntity); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%newEntity); + } + + EWorldEditor.isDirty = true; +} + +function GuiInspectorTypeShapeAssetPtr::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + + if(%assetType $= "ShapeAsset") + { + echo("DROPPED A SHAPE ON A SHAPE ASSET COMPONENT FIELD!"); + + %module = %payload.dragSourceControl.parentGroup.moduleName; + %asset = %payload.dragSourceControl.parentGroup.assetName; + + %targetComponent = %this.ComponentOwner; + %targetComponent.MeshAsset = %module @ ":" @ %asset; + + //Inspector.refresh(); + } + + EWorldEditor.isDirty= true; +} + +function GuiInspectorTypeImageAssetPtr::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + + if(%assetType $= "ImageAsset") + { + echo("DROPPED A IMAGE ON AN IMAGE ASSET COMPONENT FIELD!"); + } + + EWorldEditor.isDirty = true; +} + +function GuiInspectorTypeMaterialAssetPtr::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + + if(%assetType $= "MaterialAsset") + { + echo("DROPPED A MATERIAL ON A MATERIAL ASSET COMPONENT FIELD!"); + } + + EWorldEditor.isDirty = true; +} + +function AssetBrowserFilterTree::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + %assetName = %payload.dragSourceControl.parentGroup.assetName; + %moduleName = %payload.dragSourceControl.parentGroup.moduleName; + + echo("DROPPED A " @ %assetType @ " ON THE ASSET BROWSER NAVIGATION TREE!"); + + %item = %this.getItemAtPosition(%position); + + echo("DROPPED IT ON ITEM " @ %item); + + %parent = %this.getParentItem(%item); + + if(%parent == 1) + { + //we're a module entry, cool + %targetModuleName = %this.getItemText(%item); + echo("DROPPED IT ON MODULE " @ %targetModuleName); + + if(%moduleName !$= %targetModuleName) + { + //we're trying to move the asset to a different module! + MessageBoxYesNo( "Move Asset", "Do you wish to move asset " @ %assetName @ " to module " @ %targetModuleName @ "?", + "AssetBrowser.moveAsset("@%assetName@", "@%targetModuleName@");", ""); + } + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs new file mode 100644 index 000000000..8732ac8a5 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs @@ -0,0 +1,1525 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// +// +function isImageFormat(%fileExt) +{ + if( (%fileExt $= ".png") || (%fileExt $= ".jpg") || (%fileExt $= ".bmp") || (%fileExt $= ".dds") || (%fileExt $= ".tif")) + return true; + + return false; +} + +function isShapeFormat(%fileExt) +{ + if( (%fileExt $= ".dae") || (%fileExt $= ".dts") || (%fileExt $= ".fbx") || (%fileExt $= ".obj") || (%fileExt $= ".blend")) + return true; + + return false; +} + +function isSoundFormat(%fileExt) +{ + if( (%fileExt $= ".ogg") || (%fileExt $= ".wav") || (%fileExt $= ".mp3")) + return true; + + return false; +} + +function getImageInfo(%file) +{ + //we're going to populate a GuiTreeCtrl with info of the inbound image file +} + +//This lets us go and look for a image at the importing directory as long as it matches the material name +function findImageFile(%path, %materialName, %type) +{ + + if(isFile(%path @ "/" @ %materialName @ ".jpg")) + return %path @ "/" @ %materialName @ ".jpg"; + else if(isFile(%path @ "/" @ %materialName @ ".png")) + return %path @ "/" @ %materialName @ ".png"; + else if(isFile(%path @ "/" @ %materialName @ ".dds")) + return %path @ "/" @ %materialName @ ".dds"; + else if(isFile(%path @ "/" @ %materialName @ ".tif")) + return %path @ "/" @ %materialName @ ".tif"; +} + +function AssetBrowser::onBeginDropFiles( %this ) +{ + error("% DragDrop - Beginning files dropping."); + %this.importAssetNewListArray.empty(); + %this.importAssetUnprocessedListArray.empty(); + %this.importAssetFinalListArray.empty(); +} + +function AssetBrowser::onDropFile( %this, %filePath ) +{ + if(!%this.isVisible()) + return; + + %fileExt = fileExt( %filePath ); + //add it to our array! + if(isImageFormat(%fileExt)) + %this.addImportingAsset("Image", %filePath); + else if( isShapeFormat(%fileExt)) + %this.addImportingAsset("Model", %filePath); + else if( isSoundFormat(%fileExt)) + %this.addImportingAsset("Sound", %filePath); + else if (%fileExt $= ".zip") + %this.onDropZipFile(%filePath); +} + +function AssetBrowser::onDropZipFile(%this, %filePath) +{ + if(!%this.isVisible()) + return; + + %zip = new ZipObject(); + %zip.openArchive(%filePath); + %count = %zip.getFileEntryCount(); + + echo("Dropped in a zip file with" SPC %count SPC "files inside!"); + + return; + for (%i = 0; %i < %count; %i++) + { + %fileEntry = %zip.getFileEntry(%i); + %fileFrom = getField(%fileEntry, 0); + + //First, we wanna scan to see if we have modules to contend with. If we do, we'll just plunk them in wholesale + //and not process their contents. + + //If not modules, it's likely an art pack or other mixed files, so we'll import them as normal + if( (%fileExt $= ".png") || (%fileExt $= ".jpg") || (%fileExt $= ".bmp") || (%fileExt $= ".dds") ) + %this.importAssetListArray.add("Image", %filePath); + else if( (%fileExt $= ".dae") || (%fileExt $= ".dts")) + %this.importAssetListArray.add("Model", %filePath); + else if( (%fileExt $= ".ogg") || (%fileExt $= ".wav") || (%fileExt $= ".mp3")) + %this.importAssetListArray.add("Sound", %filePath); + else if( (%fileExt $= ".gui") || (%fileExt $= ".gui.dso")) + %this.importAssetListArray.add("GUI", %filePath); + //else if( (%fileExt $= ".cs") || (%fileExt $= ".dso")) + // %this.importAssetListArray.add("Script", %filePath); + else if( (%fileExt $= ".mis")) + %this.importAssetListArray.add("Level", %filePath); + + // For now, if it's a .cs file, we'll assume it's a behavior. + if (fileExt(%fileFrom) !$= ".cs") + continue; + + %fileTo = expandFilename("^game/behaviors/") @ fileName(%fileFrom); + %zip.extractFile(%fileFrom, %fileTo); + exec(%fileTo); + } +} + +function AssetBrowser::onDropImageFile(%this, %filePath) +{ + if(!%this.isVisible()) + return; + + // File Information madness + %fileName = %filePath; + %fileOnlyName = fileName( %fileName ); + %fileBase = validateDatablockName(fileBase( %fileName ) @ "ImageMap"); + + // [neo, 5/17/2007 - #3117] + // Check if the file being dropped is already in data/images or a sub dir by checking if + // the file path up to length of check path is the same as check path. + %defaultPath = EditorSettings.value( "WorldEditor/defaultMaterialsPath" ); + + %checkPath = expandFilename( "^"@%defaultPath ); + %fileOnlyPath = expandFileName( %filePath ); //filePath( expandFileName( %filePath ) ); + %fileBasePath = getSubStr( %fileOnlyPath, 0, strlen( %checkPath ) ); + + if( %checkPath !$= %fileBasePath ) + { + // No match so file is from outside images directory and we need to copy it in + %fileNewLocation = expandFilename("^"@%defaultPath) @ "/" @ fileBase( %fileName ) @ fileExt( %fileName ); + + // Move to final location + if( !pathCopy( %filePath, %fileNewLocation ) ) + return; + } + else + { + // Already in images path somewhere so just link to it + %fileNewLocation = %filePath; + } + + addResPath( filePath( %fileNewLocation ) ); + + %matName = fileBase( %fileName ); + + // Create Material + %imap = new Material(%matName) + { + mapTo = fileBase( %matName ); + diffuseMap[0] = %defaultPath @ "/" @ fileBase( %fileName ) @ fileExt( %fileName ); + }; + //%imap.setName( %fileBase ); + //%imap.imageName = %fileNewLocation; + //%imap.imageMode = "FULL"; + //%imap.filterPad = false; + //%imap.compile(); + + %diffusecheck = %imap.diffuseMap[0]; + + // Bad Creation! + if( !isObject( %imap ) ) + return; + + %this.addDatablock( %fileBase, false ); +} + +function AssetBrowser::onDropSoundFile(%this, %filePath) +{ + if(!%this.isVisible()) + return; + + // File Information madness + %fileName = %filePath; + %fileOnlyName = fileName( %fileName ); + %fileBase = validateDatablockName(fileBase( %fileName ) @ "ImageMap"); + + // [neo, 5/17/2007 - #3117] + // Check if the file being dropped is already in data/images or a sub dir by checking if + // the file path up to length of check path is the same as check path. + %defaultPath = EditorSettings.value( "WorldEditor/defaultMaterialsPath" ); + + %checkPath = expandFilename( "^"@%defaultPath ); + %fileOnlyPath = expandFileName( %filePath ); //filePath( expandFileName( %filePath ) ); + %fileBasePath = getSubStr( %fileOnlyPath, 0, strlen( %checkPath ) ); + + if( %checkPath !$= %fileBasePath ) + { + // No match so file is from outside images directory and we need to copy it in + %fileNewLocation = expandFilename("^"@%defaultPath) @ "/" @ fileBase( %fileName ) @ fileExt( %fileName ); + + // Move to final location + if( !pathCopy( %filePath, %fileNewLocation ) ) + return; + } + else + { + // Already in images path somewhere so just link to it + %fileNewLocation = %filePath; + } + + addResPath( filePath( %fileNewLocation ) ); + + %matName = fileBase( %fileName ); + + // Create Material + %imap = new Material(%matName) + { + mapTo = fileBase( %matName ); + diffuseMap[0] = %defaultPath @ "/" @ fileBase( %fileName ) @ fileExt( %fileName ); + }; + //%imap.setName( %fileBase ); + //%imap.imageName = %fileNewLocation; + //%imap.imageMode = "FULL"; + //%imap.filterPad = false; + //%imap.compile(); + + %diffusecheck = %imap.diffuseMap[0]; + + // Bad Creation! + if( !isObject( %imap ) ) + return; + + %this.addDatablock( %fileBase, false ); +} + +function AssetBrowser::onEndDropFiles( %this ) +{ + if(!%this.isVisible()) + return; + + //we have assets to import, so go ahead and display the window for that now + Canvas.pushDialog(AssetImportCtrl); + ImportAssetWindow.visible = true; + //ImportAssetWindow.validateAssets(); + ImportAssetWindow.refresh(); + ImportAssetWindow.selectWindow(); + + // Update object library + GuiFormManager::SendContentMessage($LBCreateSiderBar, %this, "refreshAll 1"); + + if(ImportAssetWindow.importConfigsList.count() == 0) + { + MessageBoxOK( "Warning", "No base import config. Please create an import configuration set to simplify asset importing."); + } +} +// +// +// + +function AssetBrowser::addImportingAsset( %this, %assetType, %filePath, %parentAssetItem ) +{ + %assetName = fileBase(%filePath); + %filePath = filePath(%filePath) @ "/" @ fileBase(%filePath) @ fileExt(%filePath); //sanitize the file path + + %moduleName = AssetBrowser.SelectedModule; + ImportAssetModuleList.text = %moduleName; + + //Add to our main list + %assetItem = new ScriptObject() + { + assetType = %assetType; + filePath = %filePath; + assetName = %assetName; + moduleName = %moduleName; + dirty = true; + parentAssetItem = %parentAssetItem; + status = ""; + statusType = ""; + statusInfo = ""; + skip = false; + }; + + //little bit of interception here + if(%assetItem.assetType $= "Model") + { + %fileExt = fileExt(%assetItem.filePath); + if(%fileExt $= ".dae") + { + %shapeInfo = new GuiTreeViewCtrl(); + enumColladaForImport(%assetItem.filePath, %shapeInfo); + } + else + { + %shapeInfo = GetShapeInfo(%assetItem.filePath); + } + + %assetItem.shapeInfo = %shapeInfo; + + %shapeItem = %assetItem.shapeInfo.findItemByName("Shape"); + %shapeCount = %assetItem.shapeInfo.getItemValue(%shapeItem); + + %animItem = %assetItem.shapeInfo.findItemByName("Animations"); + %animCount = %assetItem.shapeInfo.getItemValue(%animItem); + + //If the model has shapes AND animations, then it's a normal shape with embedded animations + //if it has shapes and no animations it's a regular static mesh + //if it has no shapes and animations, it's a special case. This means it's a shape animation only file so it gets flagged as special + if(%shapeCount == 0 && %animCount != 0) + { + %assetItem.assetType = "Animation"; + } + else if(%shapeCount == 0 && %animCount == 0) + { + //either it imported wrong or it's a bad file we can't read. Either way, don't try importing it + error("Error - attempted to import a model file with no shapes or animations! Model in question was: " @ %filePath); + + %assetItem.delete(); + return 0; + } + } + + if(%parentAssetItem $= "") + { + %assetItem.parentDepth = 0; + %this.importAssetNewListArray.add(%assetItem); + %this.importAssetUnprocessedListArray.add(%assetItem); + } + else + { + %assetItem.parentDepth = %parentAssetItem.parentDepth + 1; + %parentIndex = %this.importAssetUnprocessedListArray.getIndexFromKey(%parentAssetItem); + + %parentAssetItem.dependencies = %parentAssetItem.dependencies SPC %assetItem; + trim(%parentAssetItem.dependencies); + + %this.importAssetUnprocessedListArray.insert(%assetItem, "", %parentIndex + 1); + } + + return %assetItem; +} + +// +function ImportAssetButton::onClick(%this) +{ + %dlg = new OpenFileDialog() + { + Filters = "Shape Files(*.dae, *.cached.dts)|*.dae;*.cached.dts|Images Files(*.jpg,*.png,*.tga,*.bmp,*.dds)|*.jpg;*.png;*.tga;*.bmp;*.dds|Any Files (*.*)|*.*|"; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = false; + OverwritePrompt = true; + //MultipleFiles = true; + }; + + %ret = %dlg.Execute(); + + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %fullPath = makeRelativePath( %dlg.FileName, getMainDotCSDir() ); + %file = fileBase( %fullPath ); + } + + %dlg.delete(); + + if ( !%ret ) + return; + + AssetBrowser.importAssetListArray.empty(); + + %fileExt = fileExt( %fullPath ); + //add it to our array! + if( (%fileExt $= ".png") || (%fileExt $= ".jpg") || (%fileExt $= ".bmp") || (%fileExt $= ".dds") ) + AssetBrowser.importAssetListArray.add("Image", %fullPath); + else if( (%fileExt $= ".dae") || (%fileExt $= ".dts")) + AssetBrowser.importAssetListArray.add("Model", %fullPath); + else if( (%fileExt $= ".ogg") || (%fileExt $= ".wav") || (%fileExt $= ".mp3")) + AssetBrowser.importAssetListArray.add("Sound", %fullPath); + else if (%fileExt $= ".zip") + AssetBrowser.onDropZipFile(%fullPath); + + ImportAssetConfigWindow.visible = true; + ImportAssetConfigWindow.refresh(); + ImportAssetConfigWindow.selectWindow(); +} +// + +// +function ImportAssetWindow::onWake(%this) +{ + //We've woken, meaning we're trying to import assets + //Lets refresh our list + if(!ImportAssetWindow.isVisible()) + return; + + $AssetBrowser::importConfigsFile = "tools/assetBrowser/assetImportConfigs.xml"; + + %this.reloadImportOptionConfigs(); +} + +function ImportAssetWindow::reloadImportOptionConfigs(%this) +{ + ImportAssetWindow.importConfigsList = new ArrayObject(); + ImportAssetConfigList.clear(); + + %xmlDoc = new SimXMLDocument(); + if(%xmlDoc.loadFile($AssetBrowser::importConfigsFile)) + { + //StateMachine element + %xmlDoc.pushFirstChildElement("AssetImportConfigs"); + + //Configs + %configCount = 0; + while(%xmlDoc.pushChildElement(%configCount)) + { + %configObj = new ScriptObject(){}; + + %configObj.Name = %xmlDoc.attribute("Name"); + + %xmlDoc.pushFirstChildElement("Mesh"); + %configObj.ImportMesh = %xmlDoc.attribute("ImportMesh"); + %configObj.DoUpAxisOverride = %xmlDoc.attribute("DoUpAxisOverride"); + %configObj.UpAxisOverride = %xmlDoc.attribute("UpAxisOverride"); + %configObj.DoScaleOverride = %xmlDoc.attribute("DoScaleOverride"); + %configObj.ScaleOverride = %xmlDoc.attribute("ScaleOverride"); + %configObj.IgnoreNodeScale = %xmlDoc.attribute("IgnoreNodeScale"); + %configObj.AdjustCenter = %xmlDoc.attribute("AdjustCenter"); + %configObj.AdjustFloor = %xmlDoc.attribute("AdjustFloor"); + %configObj.CollapseSubmeshes = %xmlDoc.attribute("CollapseSubmeshes"); + %configObj.LODType = %xmlDoc.attribute("LODType"); + %configObj.ImportedNodes = %xmlDoc.attribute("ImportedNodes"); + %configObj.IgnoreNodes = %xmlDoc.attribute("IgnoreNodes"); + %configObj.ImportMeshes = %xmlDoc.attribute("ImportMeshes"); + %configObj.IgnoreMeshes = %xmlDoc.attribute("IgnoreMeshes"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Materials"); + %configObj.ImportMaterials = %xmlDoc.attribute("ImportMaterials"); + %configObj.CreateComposites = %xmlDoc.attribute("CreateComposites"); + %configObj.UseDiffuseSuffixOnOriginImg = %xmlDoc.attribute("UseDiffuseSuffixOnOriginImg"); + %configObj.UseExistingMaterials = %xmlDoc.attribute("UseExistingMaterials"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Animations"); + %configObj.ImportAnimations = %xmlDoc.attribute("ImportAnimations"); + %configObj.SeparateAnimations = %xmlDoc.attribute("SeparateAnimations"); + %configObj.SeparateAnimationPrefix = %xmlDoc.attribute("SeparateAnimationPrefix"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Collisions"); + %configObj.GenerateCollisions = %xmlDoc.attribute("GenerateCollisions"); + %configObj.GenCollisionType = %xmlDoc.attribute("GenCollisionType"); + %configObj.CollisionMeshPrefix = %xmlDoc.attribute("CollisionMeshPrefix"); + %configObj.GenerateLOSCollisions = %xmlDoc.attribute("GenerateLOSCollisions"); + %configObj.GenLOSCollisionType = %xmlDoc.attribute("GenLOSCollisionType"); + %configObj.LOSCollisionMeshPrefix = %xmlDoc.attribute("LOSCollisionMeshPrefix"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Images"); + %configObj.ImageType = %xmlDoc.attribute("ImageType"); + %configObj.DiffuseTypeSuffixes = %xmlDoc.attribute("DiffuseTypeSuffixes"); + %configObj.NormalTypeSuffixes = %xmlDoc.attribute("NormalTypeSuffixes"); + %configObj.SpecularTypeSuffixes = %xmlDoc.attribute("SpecularTypeSuffixes"); + %configObj.MetalnessTypeSuffixes = %xmlDoc.attribute("MetalnessTypeSuffixes"); + %configObj.RoughnessTypeSuffixes = %xmlDoc.attribute("RoughnessTypeSuffixes"); + %configObj.SmoothnessTypeSuffixes = %xmlDoc.attribute("SmoothnessTypeSuffixes"); + %configObj.AOTypeSuffixes = %xmlDoc.attribute("AOTypeSuffixes"); + %configObj.CompositeTypeSuffixes = %xmlDoc.attribute("CompositeTypeSuffixes"); + %configObj.TextureFilteringMode = %xmlDoc.attribute("TextureFilteringMode"); + %configObj.UseMips = %xmlDoc.attribute("UseMips"); + %configObj.IsHDR = %xmlDoc.attribute("IsHDR"); + %configObj.Scaling = %xmlDoc.attribute("Scaling"); + %configObj.Compressed = %xmlDoc.attribute("Compressed"); + %configObj.GenerateMaterialOnImport = %xmlDoc.attribute("GenerateMaterialOnImport"); + %configObj.PopulateMaterialMaps = %xmlDoc.attribute("PopulateMaterialMaps"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Sounds"); + %configObj.VolumeAdjust = %xmlDoc.attribute("VolumeAdjust"); + %configObj.PitchAdjust = %xmlDoc.attribute("PitchAdjust"); + %configObj.Compressed = %xmlDoc.attribute("Compressed"); + %xmlDoc.popElement(); + + %xmlDoc.popElement(); + %configCount++; + + ImportAssetWindow.importConfigsList.add(%configObj); + } + + %xmlDoc.popElement(); + } + + for(%i = 0; %i < ImportAssetWindow.importConfigsList.count(); %i++) + { + %configObj = ImportAssetWindow.importConfigsList.getKey(%i); + ImportAssetConfigList.add(%configObj.Name); + } + + ImportAssetConfigList.setSelected(0); +} + +function ImportAssetWindow::setImportOptions(%this, %optionsObj) +{ + //Todo, editor + load from files for preconfigs + + //Meshes + %optionsObj.ImportMesh = true; + %optionsObj.UpAxisOverride = "Z_AXIS"; + %optionsObj.OverrideScale = 1.0; + %optionsObj.IgnoreNodeScale = false; + %optionsObj.AdjustCenter = false; + %optionsObj.AdjustFloor = false; + %optionsObj.CollapseSubmeshes = false; + %optionsObj.LODType = "TrailingNumber"; + %optionsObj.TrailingNumber = 2; + %optionsObj.ImportedNodes = ""; + %optionsObj.IgnoreNodes = ""; + %optionsObj.ImportMeshes = ""; + %optionsObj.IgnoreMeshes = ""; + + //Materials + %optionsObj.ImportMaterials = true; + %optionsObj.CreateComposites = true; + + //Animations + %optionsObj.ImportAnimations = true; + %optionsObj.SeparateAnimations = true; + %optionsObj.SeparateAnimationPrefix = ""; + + //Collision + %optionsObj.GenerateCollisions = true; + %optionsObj.GenCollisionType = "CollisionMesh"; + %optionsObj.CollisionMeshPrefix = "Collision"; + %optionsObj.GenerateLOSCollisions = true; + %optionsObj.GenLOSCollisionType = "CollisionMesh"; + %optionsObj.LOSCollisionMeshPrefix = "LOS"; + + //Images + %optionsObj.ImageType = "Diffuse"; + %optionsObj.DiffuseTypeSuffixes = "_ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL"; + %optionsObj.NormalTypeSuffixes = "_NORMAL,_NORM"; + %optionsObj.SpecularTypeSuffixes = "_SPECULAR,_SPEC"; + %optionsObj.MetalnessTypeSuffixes = "_METAL,_MET,_METALNESS,_METALLIC"; + %optionsObj.RoughnessTypeSuffixes = "_ROUGH,_ROUGHNESS"; + %optionsObj.SmoothnessTypeSuffixes = "_SMOOTH,_SMOOTHNESS"; + %optionsObj.AOTypeSuffixes = "_AO,_AMBIENT,_AMBIENTOCCLUSION"; + %optionsObj.CompositeTypeSuffixes = "_COMP,_COMPOSITE"; + %optionsObj.TextureFilteringMode = "Bilinear"; + %optionsObj.UseMips = true; + %optionsObj.IsHDR = false; + %optionsObj.Scaling = 1.0; + %optionsObj.Compressed = true; + + //Sounds + %optionsObj.VolumeAdjust = 1.0; + %optionsObj.PitchAdjust = 1.0; + %optionsObj.Compressed = false; +} + +// +function ImportAssetWindow::processNewImportAssets(%this) +{ + %unprocessedCount = AssetBrowser.importAssetUnprocessedListArray.count(); + while(AssetBrowser.importAssetUnprocessedListArray.count() > 0) + { + %assetItem = AssetBrowser.importAssetUnprocessedListArray.getKey(0); + + %assetConfigObj = ImportAssetWindow.activeImportConfig.clone(); + %assetConfigObj.assetIndex = %i; + %assetConfigObj.assetName = %assetItem.assetName; + %assetItem.importConfig = %assetConfigObj; + + if(%assetItem.assetType $= "Model") + { + %fileExt = fileExt(%assetItem.filePath); + if(%fileExt $= ".dae") + { + %shapeInfo = new GuiTreeViewCtrl(); + enumColladaForImport(%assetItem.filePath, %shapeInfo); + } + else + { + %shapeInfo = GetShapeInfo(%assetItem.filePath); + } + + %assetItem.shapeInfo = %shapeInfo; + + %shapeItem = %assetItem.shapeInfo.findItemByName("Shape"); + %shapeCount = %assetItem.shapeInfo.getItemValue(%shapeItem); + + if(%assetConfigObj.ImportMesh == 1 && %shapeCount > 0) + { + + } + + %animItem = %assetItem.shapeInfo.findItemByName("Animations"); + %animCount = %assetItem.shapeInfo.getItemValue(%animItem); + + if(%assetConfigObj.ImportAnimations == 1 && %animCount > 0) + { + %animationItem = %assetItem.shapeInfo.getChild(%animItem); + + %animName = %assetItem.shapeInfo.getItemText(%animationItem); + //%animName = %assetItem.shapeInfo.getItemValue(%animationItem); + + AssetBrowser.addImportingAsset("Animation", %animName, %assetItem); + + %animationItem = %assetItem.shapeInfo.getNextSibling(%animationItem); + while(%animationItem != 0) + { + %animName = %assetItem.shapeInfo.getItemText(%animationItem); + //%animName = %assetItem.shapeInfo.getItemValue(%animationItem); + + AssetBrowser.addImportingAsset("Animation", %animName, %assetItem); + + %animationItem = %shapeInfo.getNextSibling(%animationItem); + } + } + + %matItem = %assetItem.shapeInfo.findItemByName("Materials"); + %matCount = %assetItem.shapeInfo.getItemValue(%matItem); + + if(%assetConfigObj.importMaterials == 1 && %matCount > 0) + { + %materialItem = %assetItem.shapeInfo.getChild(%matItem); + + %matName = %assetItem.shapeInfo.getItemText(%materialItem); + + %filePath = %assetItem.shapeInfo.getItemValue(%materialItem); + if(%filePath !$= "") + { + AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + } + else + { + //we need to try and find our material, since the shapeInfo wasn't able to find it automatically + %filePath = findImageFile(filePath(%assetItem.filePath), %matName); + if(%filePath !$= "") + AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + else + AssetBrowser.addImportingAsset("Material", %matName, %assetItem); + } + + %materialItem = %assetItem.shapeInfo.getNextSibling(%materialItem); + while(%materialItem != 0) + { + %matName = %assetItem.shapeInfo.getItemText(%materialItem); + %filePath = %assetItem.shapeInfo.getItemValue(%materialItem); + if(%filePath !$= "") + { + AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + } + else + { + //we need to try and find our material, since the shapeInfo wasn't able to find it automatically + %filePath = findImageFile(filePath(%assetItem.filePath), %matName); + if(%filePath !$= "") + AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + else + AssetBrowser.addImportingAsset("Material", %matName, %assetItem); + } + + %materialItem = %shapeInfo.getNextSibling(%materialItem); + } + } + } + else if(%assetItem.assetType $= "Animation") + { + //if we don't have our own file, that means we're gunna be using our parent shape's file so reference that + if(!isFile(%assetItem.filePath)) + { + %assetItem.filePath = %assetItem.parentAssetItem.filePath; + } + } + else if(%assetItem.assetType $= "Material") + { + //Iterate over to find appropriate images for + + //Fetch just the fileBase name + %fileDir = filePath(%assetItem.filePath); + %filename = fileBase(%assetItem.filePath); + %fileExt = fileExt(%assetItem.filePath); + + if(%assetItem.importConfig.PopulateMaterialMaps == 1) + { + if(%assetItem.diffuseImageAsset $= "") + { + //First, load our diffuse map, as set to the material in the shape + %diffuseAsset = AssetBrowser.addImportingAsset("Image", %fileDir @ "/" @ %filename @ %fileExt, %assetItem); + %assetItem.diffuseImageAsset = %diffuseAsset; + + if(%assetItem.importConfig.UseDiffuseSuffixOnOriginImg == 1) + { + %diffuseToken = getToken(%assetItem.importConfig.DiffuseTypeSuffixes, ",", 0); + %diffuseAsset.AssetName = %diffuseAsset.AssetName @ %diffuseToken; + } + } + + if(%assetItem.normalImageAsset $= "") + { + //Now, iterate over our comma-delimited suffixes to see if we have any matches. We'll use the first match in each case, if any. + //First, normal map + %listCount = getTokenCount(%assetItem.importConfig.NormalTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.NormalTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %normalAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.normalImageAsset = %normalAsset; + break; + } + } + } + if(%assetItem.specularImageAsset $= "") + { + //Specular + %listCount = getTokenCount(%assetItem.importConfig.SpecularTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.SpecularTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %specularAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.specularImageAsset = %specularAsset; + break; + } + } + } + + if(%assetItem.metalImageAsset $= "") + { + //Metal + %listCount = getTokenCount(%assetItem.importConfig.MetalnessTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.MetalnessTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %metalAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.metalImageAsset = %metalAsset; + break; + } + } + } + + if(%assetItem.roughnessImageAsset $= "") + { + //Roughness + %listCount = getTokenCount(%assetItem.importConfig.RoughnessTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.RoughnessTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %roughnessAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.roughnessImageAsset = %roughnessAsset; + break; + } + } + } + + if(%assetItem.smoothnessImageAsset $= "") + { + //Smoothness + %listCount = getTokenCount(%assetItem.importConfig.SmoothnessTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.SmoothnessTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %smoothnessAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.SmoothnessImageAsset = %smoothnessAsset; + break; + } + } + } + + if(%assetItem.AOImageAsset $= "") + { + //AO + %listCount = getTokenCount(%assetItem.importConfig.AOTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.AOTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %AOAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.AOImageAsset = %AOAsset; + break; + } + } + } + + if(%assetItem.compositeImageAsset $= "") + { + //Composite + %listCount = getTokenCount(%assetItem.importConfig.CompositeTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.CompositeTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %compositeAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.compositeImageAsset = %compositeAsset; + break; + } + } + } + } + } + else if(%assetItem.assetType $= "Image") + { + if(%assetConfigObj.GenerateMaterialOnImport == 1 && %assetItem.parentAssetItem $= "") + { + %filePath = %assetItem.filePath; + if(%filePath !$= "") + %materialAsset = AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + + %materialAsset.diffuseImageAsset = %assetItem; + + if(%assetConfigObj.UseDiffuseSuffixOnOriginImg == 1) + { + %diffuseToken = getToken(%assetItem.importConfig.DiffuseTypeSuffixes, ",", 0); + %assetItem.AssetName = %assetItem.AssetName @ %diffuseToken; + } + } + } + + AssetBrowser.importAssetUnprocessedListArray.erase(0); + //Been processed, so add it to our final list + AssetBrowser.importAssetFinalListArray.add(%assetItem); + } +} + +function ImportAssetWindow::refresh(%this) +{ + ImportingAssetList.clear(); + + //Go through and process any newly, unprocessed assets + %this.processNewImportAssets(); + + if(AssetBrowser.importAssetUnprocessedListArray.count() == 0) + { + //We've processed them all, prep the assets for actual importing + //Initial set of assets + %assetCount = AssetBrowser.importAssetFinalListArray.count(); + + for(%i=0; %i < %assetCount; %i++) + { + %assetItem = AssetBrowser.importAssetFinalListArray.getKey(%i); + %assetType = %assetItem.assetType; + %filePath = %assetItem.filePath; + %assetName = %assetItem.assetName; + + //validate + %this.validateAsset(%assetItem); + + //Once validated, attempt any fixes for issues + %this.resolveIssue(%assetItem); + + //Make sure we size correctly + ImportingAssetList.extent.x = ImportingAssetList.getParent().extent.x - 15; + + //create! + %width = mRound(mRound(ImportingAssetList.extent.x) / 2); + %height = 20; + %indent = %assetItem.parentDepth * 16; + %toolTip = ""; + + %iconPath = "tools/gui/images/iconInformation"; + %configCommand = "ImportAssetOptionsWindow.editImportSettings(" @ %assetItem @ ");"; + + if(%assetType $= "Model" || %assetType $= "Animation" || %assetType $= "Image" || %assetType $= "Sound") + { + if(%assetItem.status $= "Error") + { + %iconPath = "tools/gui/images/iconError"; + %configCommand = "ImportAssetOptionsWindow.findMissingFile(" @ %assetItem @ ");"; + } + else if(%assetItem.status $= "Warning") + { + %iconPath = "tools/gui/images/iconWarn"; + %configCommand = "ImportAssetOptionsWindow.fixIssues(" @ %assetItem @ ");"; + + if(%assetItem.statusType $= "DuplicateAsset" || %assetItem.statusType $= "DuplicateImportAsset") + %assetName = %assetItem.assetName @ " "; + } + + %toolTip = %assetItem.statusInfo; + } + else + { + if(%assetItem.status $= "Error") + { + %iconPath = "tools/gui/images/iconError"; + %configCommand = "";//"ImportAssetOptionsWindow.findMissingFile(" @ %assetItem @ ");"; + } + else if(%assetItem.status $= "Warning") + { + %iconPath = "tools/gui/images/iconWarn"; + %configCommand = "";//"ImportAssetOptionsWindow.fixIssues(" @ %assetItem @ ");"; + + if(%assetItem.statusType $= "DuplicateAsset" || %assetItem.statusType $= "DuplicateImportAsset") + %assetName = %assetItem.assetName @ " "; + } + } + + %importEntry = new GuiControl() + { + position = "0 0"; + extent = ImportingAssetList.extent.x SPC %height; + + new GuiTextCtrl() + { + Text = %assetName; + position = %indent SPC "0"; + extent = %width - %indent SPC %height; + internalName = "AssetName"; + }; + + new GuiTextCtrl() + { + Text = %assetType; + position = %width SPC "0"; + extent = %width - %height - %height SPC %height; + internalName = "AssetType"; + }; + + new GuiBitmapButtonCtrl() + { + position = ImportingAssetList.extent.x - %height - %height SPC "0"; + extent = %height SPC %height; + command = %configCommand; + bitmap = %iconPath; + tooltip = %toolTip; + }; + new GuiBitmapButtonCtrl() + { + position = ImportingAssetList.extent.x - %height SPC "0"; + extent = %height SPC %height; + command = "ImportAssetOptionsWindow.deleteImportingAsset(" @ %assetItem @ ");"; + bitmap = "tools/gui/images/iconDelete"; + }; + }; + + ImportingAssetList.add(%importEntry); + } + } + else + { + //Continue processing + %this.refresh(); + } +} +// + +function ImportAssetWindow::validateAssets(%this) +{ + %assetCount = AssetBrowser.importAssetFinalListArray.count(); + %moduleName = ImportAssetModuleList.getText(); + %assetQuery = new AssetQuery(); + + %hasIssues = false; + + //First, check the obvious: name collisions. We should have no asset that shares a similar name. + //If we do, prompt for it be renamed first before continuing + + for(%i=0; %i < %assetCount; %i++) + { + %assetItemA = AssetBrowser.importAssetFinalListArray.getKey(%i); + + //First, check our importing assets for name collisions + for(%j=0; %j < %assetCount; %j++) + { + %assetItemB = AssetBrowser.importAssetFinalListArray.getKey(%j); + if( (%assetItemA.assetName $= %assetItemB.assetName) && (%i != %j) ) + { + //yup, a collision, prompt for the change and bail out + /*MessageBoxOK( "Error!", "Duplicate asset names found with importing assets!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" and \"" @ + %assetItemB.assetName @ "\" of type \"" @ %assetItemB.assetType @ "\" have matching names.\nPlease rename one of them and try again!");*/ + + %assetItemA.status = "Warning"; + %assetItemA.statusType = "DuplicateImportAsset"; + %assetItemA.statusInfo = "Duplicate asset names found with importing assets!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" and \"" @ + %assetItemB.assetName @ "\" of type \"" @ %assetItemB.assetType @ "\" have matching names.\nPlease rename one of them and try again!"; + + %hasIssues = true; + } + } + + //No collisions of for this name in the importing assets. Now, check against the existing assets in the target module + if(!AssetBrowser.isAssetReImport) + { + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + %foundCollision = false; + for( %f=0; %f < %numAssetsFound; %f++) + { + %assetId = %assetQuery.getAsset(%f); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %testModuleName = %module.moduleId; + + //These are core, native-level components, so we're not going to be messing with this module at all, skip it + if(%moduleName !$= %testModuleName) + continue; + + %testAssetName = AssetDatabase.getAssetName(%assetId); + + if(%testAssetName $= %assetItemA.assetName) + { + %foundCollision = true; + + %assetItemA.status = "Warning"; + %assetItemA.statusType = "DuplicateAsset"; + %assetItemA.statusInfo = "Duplicate asset names found with the target module!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" has a matching name.\nPlease rename it and try again!"; + + break; + } + } + + if(%foundCollision == true) + { + %hasIssues = true; + + //yup, a collision, prompt for the change and bail out + /*MessageBoxOK( "Error!", "Duplicate asset names found with the target module!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" has a matching name.\nPlease rename it and try again!");*/ + + //%assetQuery.delete(); + //return false; + } + } + + if(!isFile(%assetItemA.filePath)) + { + %hasIssues = true; + %assetItemA.status = "error"; + %assetItemA.statusType = "MissingFile"; + %assetItemA.statusInfo = "Unable to find file to be imported. Please select asset file."; + } + } + + //Clean up our queries + %assetQuery.delete(); + + if(%hasIssues) + return false; + else + return true; +} + +function ImportAssetWindow::ImportAssets(%this) +{ + //do the actual importing, now! + %assetCount = AssetBrowser.importAssetFinalListArray.count(); + + //get the selected module data + %moduleName = ImportAssetModuleList.getText(); + + %module = ModuleDatabase.findModule(%moduleName, 1); + + if(!isObject(%module)) + { + MessageBoxOK( "Error!", "No module selected. You must select or create a module for the assets to be added to."); + return; + } + + /*if(!%this.validateAssets()) + { + //Force a refresh, as some things may have changed, such as errors and failure info! + refresh(); + + return; + }*/ + + for(%i=0; %i < %assetCount; %i++) + { + %assetItem = AssetBrowser.importAssetFinalListArray.getKey(%i); + %assetType = %assetItem.AssetType; + %filePath = %assetItem.filePath; + %assetName = %assetItem.assetName; + %assetImportSuccessful = false; + %assetId = %moduleName@":"@%assetName; + + if(%assetType $= "Image") + { + %assetPath = "data/" @ %moduleName @ "/Images"; + %assetFullPath = %assetPath @ "/" @ fileName(%filePath); + + %newAsset = new ImageAsset() + { + assetName = %assetName; + versionId = 1; + imageFile = %assetFullPath; + originalFilePath = %filePath; + }; + + %assetImportSuccessful = TAMLWrite(%newAsset, %assetPath @ "/" @ %assetName @ ".asset.taml"); + + //and copy the file into the relevent directory + %doOverwrite = !AssetBrowser.isAssetReImport; + if(!pathCopy(%filePath, %assetFullPath, %doOverwrite)) + { + error("Unable to import asset: " @ %filePath); + } + } + else if(%assetType $= "Model") + { + %assetPath = "data/" @ %moduleName @ "/Shapes"; + %assetFullPath = %assetPath @ "/" @ fileName(%filePath); + + %newAsset = new ShapeAsset() + { + assetName = %assetName; + versionId = 1; + fileName = %assetFullPath; + originalFilePath = %filePath; + isNewShape = true; + }; + + %dependencyCount = getWordCount(%assetItem.dependencies); + for(%d=0; %d < %dependencyCount; %d++) + { + %dependencyAssetItem = getWord(%assetItem.dependencies, %d); + + %depAssetType = %dependencyAssetItem.assetType; + if(%depAssetType $= "Material") + { + %matSet = "%newAsset.materialSlot"@%d@"=\"@Asset="@%moduleName@":"@%dependencyAssetItem.assetName@"\";"; + eval(%matSet); + } + if(%depAssetType $= "Animation") + { + %matSet = "%newAsset.animationSequence"@%d@"=\"@Asset="@%moduleName@":"@%dependencyAssetItem.assetName@"\";"; + eval(%matSet); + } + } + + %assetImportSuccessful = TAMLWrite(%newAsset, %assetPath @ "/" @ %assetName @ ".asset.taml"); + + //and copy the file into the relevent directory + %doOverwrite = !AssetBrowser.isAssetReImport; + if(!pathCopy(%filePath, %assetFullPath, %doOverwrite)) + { + error("Unable to import asset: " @ %filePath); + } + + //now, force-load the file if it's collada + %fileExt = fileExt(%assetFullPath); + if(isSupportedFormat(getSubStr(%fileExt,1))) + { + %tempShape = new TSStatic() + { + shapeName = %assetFullPath; + }; + + %tempShape.delete(); + } + } + else if(%assetType $= "Animation") + { + %assetPath = "data/" @ %moduleName @ "/ShapeAnimations"; + %assetFullPath = %assetPath @ "/" @ fileName(%filePath); + + %newAsset = new ShapeAnimationAsset() + { + assetName = %assetName; + versionId = 1; + fileName = %assetFullPath; + originalFilePath = %filePath; + animationFile = %assetFullPath; + animationName = %assetName; + startFrame = 0; + endFrame = -1; + padRotation = false; + padTransforms = false; + }; + + %assetImportSuccessful = TAMLWrite(%newAsset, %assetPath @ "/" @ %assetName @ ".asset.taml"); + + //and copy the file into the relevent directory + %doOverwrite = !AssetBrowser.isAssetReImport; + if(!pathCopy(%filePath, %assetFullPath, %doOverwrite)) + { + error("Unable to import asset: " @ %filePath); + } + } + else if(%assetType $= "Sound") + { + %assetPath = "data/" @ %moduleName @ "/Sounds"; + %assetFullPath = %assetPath @ "/" @ fileName(%filePath); + + %newAsset = new SoundAsset() + { + assetName = %assetName; + versionId = 1; + fileName = %assetFullPath; + originalFilePath = %filePath; + }; + + %assetImportSuccessful = TAMLWrite(%newAsset, %assetPath @ "/" @ %assetName @ ".asset.taml"); + + //and copy the file into the relevent directory + %doOverwrite = !AssetBrowser.isAssetReImport; + if(!pathCopy(%filePath, %assetFullPath, %doOverwrite)) + { + error("Unable to import asset: " @ %filePath); + } + } + else if(%assetType $= "Material") + { + %assetPath = "data/" @ %moduleName @ "/materials"; + %tamlpath = %assetPath @ "/" @ %assetName @ ".asset.taml"; + %sgfPath = %assetPath @ "/" @ %assetName @ ".sgf"; + %scriptPath = %assetPath @ "/" @ %assetName @ ".cs"; + + %newAsset = new MaterialAsset() + { + assetName = %assetName; + versionId = 1; + shaderGraph = %sgfPath; + scriptFile = %scriptPath; + originalFilePath = %filePath; + materialDefinitionName = %assetName; + }; + + %dependencyCount = getWordCount(%assetItem.dependencies); + for(%d=0; %d < %dependencyCount; %d++) + { + %dependencyAssetItem = getWord(%assetItem.dependencies, %d); + + %depAssetType = %dependencyAssetItem.assetType; + if(%depAssetType $= "Image") + { + %matSet = "%newAsset.imageMap"@%d@"=\"@Asset="@%moduleName@":"@%dependencyAssetItem.assetName@"\";"; + eval(%matSet); + } + } + + %assetImportSuccessful = TamlWrite(%newAsset, %tamlpath); + + %file = new FileObject(); + + if(%file.openForWrite(%scriptPath)) + { + %file.writeline("//--- OBJECT WRITE BEGIN ---"); + %file.writeline("singleton Material(" @ %assetName @ ") {"); + + //TODO: pass along the shape's target material for this just to be sure + %file.writeLine(" mapTo = \"" @ %assetName @ "\";"); + + if(%assetItem.diffuseImageAsset !$= "") + { + %diffuseAssetPath = "data/" @ %moduleName @ "/Images/" @ fileName(%assetItem.diffuseImageAsset.filePath); + %file.writeline(" DiffuseMap[0] = \"" @ %diffuseAssetPath @"\";"); + %file.writeline(" DiffuseMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.diffuseImageAsset.assetName @"\";"); + } + if(%assetItem.normalImageAsset) + { + %normalAssetPath = "data/" @ %moduleName @ "/Images/" @ fileName(%assetItem.normalImageAsset.filePath); + %file.writeline(" NormalMap[0] = \"" @ %normalAssetPath @"\";"); + %file.writeline(" NormalMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.normalImageAsset.assetName @"\";"); + } + /*if(%assetItem.specularImageAsset) + { + %file.writeline(" SpecularMap[0] = \"" @ %assetItem.specularImageAsset.filePath @"\";"); + %file.writeline(" SpecularMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.specularImageAsset.assetName @"\";"); + }*/ + if(%assetItem.roughnessImageAsset) + { + %file.writeline(" RoughMap[0] = \"" @ %assetItem.roughnessImageAsset.filePath @"\";"); + %file.writeline(" RoughMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.roughnessImageAsset.assetName @"\";"); + } + if(%assetItem.smoothnessImageAsset) + { + %file.writeline(" SmoothnessMap[0] = \"" @ %assetItem.smoothnessImageAsset.filePath @"\";"); + %file.writeline(" SmoothnessMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.smoothnessImageAsset.assetName @"\";"); + } + if(%assetItem.metalnessImageAsset) + { + %file.writeline(" MetalMap[0] = \"" @ %assetItem.metalnessImageAsset.filePath @"\";"); + %file.writeline(" MetalMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.metalnessImageAsset.assetName @"\";"); + } + if(%assetItem.AOImageAsset) + { + %file.writeline(" AOMap[0] = \"" @ %assetItem.AOImageAsset.filePath @"\";"); + %file.writeline(" AOMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.AOImageAsset.assetName @"\";"); + } + if(%assetItem.compositeImageAsset) + { + %file.writeline(" CompositeMap[0] = \"" @ %assetItem.compositeImageAsset.filePath @"\";"); + %file.writeline(" CompositeMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.compositeImageAsset.assetName @"\";"); + } + %file.writeline("};"); + %file.writeline("//--- OBJECT WRITE END ---"); + + %file.close(); + } + } + + if(%assetImportSuccessful) + { + %moduleDef = ModuleDatabase.findModule(%moduleName,1); + + if(!AssetBrowser.isAssetReImport) + AssetDatabase.addDeclaredAsset(%moduleDef, %assetPath @ "/" @ %assetName @ ".asset.taml"); + else + AssetDatabase.refreshAsset(%assetId); + } + } + + //force an update of any and all modules so we have an up-to-date asset list + AssetBrowser.loadFilters(); + AssetBrowser.refreshPreviews(); + Canvas.popDialog(AssetImportCtrl); + AssetBrowser.isAssetReImport = false; +} + +// +function ImportAssetWindow::validateAsset(%this, %assetItem) +{ + %assetCount = AssetBrowser.importAssetFinalListArray.count(); + %moduleName = ImportAssetModuleList.getText(); + + %hasIssues = false; + + //First, check the obvious: name collisions. We should have no asset that shares a similar name. + //If we do, prompt for it be renamed first before continuing + + for(%i=0; %i < %assetCount; %i++) + { + %assetItemA = AssetBrowser.importAssetFinalListArray.getKey(%i); + + if( (%assetItemA.assetName $= %assetItem.assetName) && (%assetItemA.getId() != %assetItem.getId()) ) + { + //yup, a collision, prompt for the change and bail out + /*MessageBoxOK( "Error!", "Duplicate asset names found with importing assets!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" and \"" @ + %assetItemB.assetName @ "\" of type \"" @ %assetItemB.assetType @ "\" have matching names.\nPlease rename one of them and try again!");*/ + + %assetItem.status = "Warning"; + %assetItem.statusType = "DuplicateImportAsset"; + %assetItem.statusInfo = "Duplicate asset names found with importing assets!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" and \"" @ + %assetItem.assetName @ "\" of type \"" @ %assetItem.assetType @ "\" have matching names.\nPlease rename one of them and try again!"; + + %hasIssues = true; + return false; + } + } + + //No collisions of for this name in the importing assets. Now, check against the existing assets in the target module + if(!AssetBrowser.isAssetReImport) + { + %assetQuery = new AssetQuery(); + + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + %foundCollision = false; + for( %f=0; %f < %numAssetsFound; %f++) + { + %assetId = %assetQuery.getAsset(%f); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %testModuleName = %module.moduleId; + + //These are core, native-level components, so we're not going to be messing with this module at all, skip it + if(%moduleName !$= %testModuleName) + continue; + + %testAssetName = AssetDatabase.getAssetName(%assetId); + + if(%testAssetName $= %assetItem.assetName) + { + %foundCollision = true; + + %assetItem.status = "Warning"; + %assetItem.statusType = "DuplicateAsset"; + %assetItem.statusInfo = "Duplicate asset names found with the target module!\nAsset \"" @ + %assetItem.assetName @ "\" of type \"" @ %assetItem.assetType @ "\" has a matching name.\nPlease rename it and try again!"; + + //Clean up our queries + %assetQuery.delete(); + + return false; + } + } + + if(%foundCollision == true) + { + %hasIssues = true; + + //yup, a collision, prompt for the change and bail out + /*MessageBoxOK( "Error!", "Duplicate asset names found with the target module!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" has a matching name.\nPlease rename it and try again!");*/ + + //%assetQuery.delete(); + //return false; + } + + //Clean up our queries + %assetQuery.delete(); + } + + if(!isFile(%assetItem.filePath)) + { + %hasIssues = true; + %assetItem.status = "error"; + %assetItem.statusType = "MissingFile"; + %assetItem.statusInfo = "Unable to find file to be imported. Please select asset file."; + + return false; + } + + return true; +} + +function ImportAssetWindow::resolveIssue(%this, %assetItem) +{ + if(%assetItem.status !$= "Warning") + return; + + //Ok, we actually have a warning, so lets resolve + if(%assetItem.statusType $= "DuplicateImportAsset" || %assetItem.statusType $= "DuplicateAsset") + { + + } + else if(%assetItem.statusType $= "MissingFile") + { + %this.findMissingFile(%assetItem); + } +} +// + +// +function ImportAssetModuleList::onWake(%this) +{ + %this.refresh(); +} + +function ImportAssetModuleList::refresh(%this) +{ + %this.clear(); + + //First, get our list of modules + %moduleList = ModuleDatabase.findModules(); + + %count = getWordCount(%moduleList); + for(%i=0; %i < %count; %i++) + { + %moduleName = getWord(%moduleList, %i); + %this.add(%moduleName.ModuleId, %i); + } +} +// diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfig.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfig.cs new file mode 100644 index 000000000..bdd4c2851 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfig.cs @@ -0,0 +1,472 @@ +function ImportAssetConfigList::onSelect( %this, %id, %text ) +{ + //Apply our settings to the assets + echo("Changed our import config!"); + AssetBrowser.importAssetUnprocessedListArray.empty(); + AssetBrowser.importAssetUnprocessedListArray.duplicate(AssetBrowser.importAssetNewListArray); + AssetBrowser.importAssetFinalListArray.empty(); + + ImportAssetWindow.activeImportConfigIndex = %id; + ImportAssetWindow.activeImportConfig = ImportAssetWindow.importConfigsList.getKey(%id); + ImportAssetWindow.refresh(); +} + +function ImportAssetOptionsWindow::findMissingFile(%this, %assetItem) +{ + if(%assetItem.assetType $= "Model") + %filters = "Shape Files(*.dae, *.cached.dts)|*.dae;*.cached.dts"; + else if(%assetItem.assetType $= "Image") + %filters = "Images Files(*.jpg,*.png,*.tga,*.bmp,*.dds)|*.jpg;*.png;*.tga;*.bmp;*.dds"; + + %dlg = new OpenFileDialog() + { + Filters = %filters; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = true; + OverwritePrompt = true; + forceRelativePath = false; + //MultipleFiles = true; + }; + + %ret = %dlg.Execute(); + + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %fullPath = %dlg.FileName;//makeRelativePath( %dlg.FileName, getMainDotCSDir() ); + } + + %dlg.delete(); + + if ( !%ret ) + return; + + %assetItem.filePath = %fullPath; + + ImportAssetWindow.refresh(); +} + +// +function ImportAssetOptionsWindow::editImportSettings(%this, %assetItem) +{ + ImportAssetOptionsWindow.setVisible(1); + ImportAssetOptionsWindow.selectWindow(); + + ImportOptionsList.clearFields(); + + %assetType = %assetItem.assetType; + %filePath = %assetItem.filePath; + %assetName = %assetItem.assetName; + %assetConfigObj = %assetItem.importConfig; + + ImportOptionsList.startGroup("Asset"); + ImportOptionsList.addField("AssetName", "Asset Name", "string", "", "NewAsset", "", %assetItem); + ImportOptionsList.endGroup(); + + if(%assetType $= "Model") + { + //Get the shape info, so we know what we're doing with the mesh + %shapeInfo = GetShapeInfo(%filePath); + %meshItem = %shapeInfo.findItemByName("Meshes"); + %matItem = %shapeInfo.findItemByName("Materials"); + + %meshCount = %shapeInfo.getItemValue(%meshItem); + %matCount = %shapeInfo.getItemValue(%matItem); + + %firstMat = %shapeInfo.getChild(%matItem); + echo("Mesh's first material texture path is: " @ %shapeInfo.getItemValue(%firstMat)); + + if(%meshCount > 0) + { + ImportOptionsList.startGroup("Mesh"); + ImportOptionsList.addField("AutogenCollisions", "Auto-gen Collisions", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("CollapseSubmeshes", "Collapse Submeshes", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("UpAxisOverride", "Up-Axis Override", "list", "", "Z_AXIS", "Z_AXIS,Y_AXIS,X_AXIS", %assetConfigObj); + ImportOptionsList.addField("OverrideScale", "Override Scale", "float", "", "1.0", "", %assetConfigObj); + ImportOptionsList.addField("IgnoreNodeScale", "IgnoreNodeScaling", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("AdjustCenter", "Adjust Center", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("CollapseSubmeshes", "Collapse Submeshes", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("AdjustFloor", "Adjust Floor", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("LODType", "LOD Type", "list", "", "TrailingNumber", "TrailingNumber,DetectDTS", %assetConfigObj); + ImportOptionsList.endGroup(); + } + + if(%matItem > 0) + { + ImportOptionsList.startGroup("Material"); + ImportOptionsList.addCallbackField("ImportMaterials", "Import Materials", "bool", "", "1", "", "ImportMaterialsChanged", %assetConfigObj); + ImportOptionsList.addField("UseExistingMaterials", "Use Existing Materials", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.endGroup(); + } + } + else if(%assetType $= "Material") + { + ImportOptionsList.startGroup("Material"); + ImportOptionsList.addField("CreateComposites", "Create Composite Textures", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.endGroup(); + } + else if(%assetType $= "Image") + { + ImportOptionsList.startGroup("Formatting"); + ImportOptionsList.addField("ImageType", "Image Type", "string", "", "Diffuse", "", %assetConfigObj); + ImportOptionsList.addField("TextureFiltering", "Texture Filtering", "list", "", "Bilinear", "None,Bilinear,Trilinear", %assetConfigObj); + ImportOptionsList.addField("UseMips", "Use Mips", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.addField("IsHDR", "Is HDR", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.endGroup(); + + ImportOptionsList.startGroup("Scaling"); + ImportOptionsList.addField("Scaling", "Scaling", "float", "", "1.0", "", %assetConfigObj); + ImportOptionsList.endGroup(); + + ImportOptionsList.startGroup("Compression"); + ImportOptionsList.addField("IsCompressed", "Is Compressed", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.endGroup(); + + ImportOptionsList.startGroup("Material"); + ImportOptionsList.addField("GenerateMaterialOnImport", "Generate Material On Import", "bool", "", "1", "", %optionsObj); + ImportOptionsList.addField("PopulateMaterialMaps", "Populate Material Maps", "bool", "", "1", "", %optionsObj); + ImportOptionsList.addField("UseDiffuseSuffixOnOriginImg", "Use Diffuse Suffix for Origin Image", "bool", "", "1", "", %optionsObj); + ImportOptionsList.addField("UseExistingMaterials", "Use Existing Materials", "bool", "", "1", "", %optionsObj); + ImportOptionsList.endGroup(); + } + else if(%assetType $= "Sound") + { + ImportOptionsList.startGroup("Adjustment"); + ImportOptionsList.addField("VolumeAdjust", "VolumeAdjustment", "float", "", "1.0", "", %assetConfigObj); + ImportOptionsList.addField("PitchAdjust", "PitchAdjustment", "float", "", "1.0", "", %assetConfigObj); + ImportOptionsList.endGroup(); + + ImportOptionsList.startGroup("Compression"); + ImportOptionsList.addField("IsCompressed", "Is Compressed", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.endGroup(); + } +} + +function ImportAssetOptionsWindow::deleteImportingAsset(%this, %assetItem) +{ + %assetIndex = AssetBrowser.importAssetNewListArray.getIndexFromKey(%assetItem); + AssetBrowser.importAssetNewListArray.erase(%assetIndex); + + //check if we have any child assets and remove them as well + for(%i=0; %i < AssetBrowser.importAssetNewListArray.count(); %i++) + { + %asset = AssetBrowser.importAssetNewListArray.getKey(%i); + if(%asset.ParentAssetItem == %assetItem) + { + AssetBrowser.importAssetNewListArray.erase(%i); + %i--; + } + } + + %assetIndex = AssetBrowser.importAssetFinalListArray.getIndexFromKey(%assetItem); + AssetBrowser.importAssetFinalListArray.erase(%assetIndex); + + //check if we have any child assets and remove them as well + for(%i=0; %i < AssetBrowser.importAssetFinalListArray.count(); %i++) + { + %asset = AssetBrowser.importAssetFinalListArray.getKey(%i); + if(%asset.ParentAssetItem == %assetItem) + { + AssetBrowser.importAssetFinalListArray.erase(%i); + %i--; + } + } + + ImportAssetWindow.refresh(); + ImportAssetOptionsWindow.setVisible(0); +} + +function ImportAssetOptionsWindow::saveAssetOptions(%this) +{ + ImportAssetWindow.refresh(); + ImportAssetOptionsWindow.setVisible(0); +} + +function ImportOptionsList::ImportMaterialsChanged(%this, %fieldName, %newValue, %ownerObject) +{ + echo("CHANGED IF OUR IMPORTED MATERIALS WERE HAPPENING!"); +} + +function ImportAssetConfigEditorWindow::populateConfigList(%this, %optionsObj) +{ + AssetImportConfigName.setText(%optionsObj.Name); + + ImportOptionsConfigList.clear(); + + ImportOptionsConfigList.startGroup("Mesh"); + ImportOptionsConfigList.addCallbackField("ImportMesh", "Import Mesh", "bool", "", "1", "", "ToggleImportMesh", %optionsObj); + ImportOptionsConfigList.addField("DoUpAxisOverride", "Do Up-axis Override", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("UpAxisOverride", "Up-axis Override", "list", "", "Z_AXIS", "X_AXIS,Y_AXIS,Z_AXIS", %optionsObj); + ImportOptionsConfigList.addField("DoScaleOverride", "Do Scale Override", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("ScaleOverride", "Scale Override", "float", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("IgnoreNodeScale", "Ignore Node Scale", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("AdjustCenter", "Adjust Center", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("AdjustFloor", "Adjust Floor", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("CollapseSubmeshes", "Collapse Submeshes", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("LODType", "LOD Type", "list", "", "TrailingNumber", "TrailingNumber,DetectDTS", %optionsObj); + //ImportOptionsConfigList.addField("TrailingNumber", "Trailing Number", "float", "", "2", "", %optionsObj, "Mesh"); + ImportOptionsConfigList.addField("ImportedNodes", "Imported Nodes", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.addField("IgnoreNodes", "Ignore Nodes", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.addField("ImportMeshes", "Import Meshes", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.addField("IgnoreMeshes", "Imported Meshes", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Materials + ImportOptionsConfigList.startGroup("Material"); + ImportOptionsConfigList.addField("ImportMaterials", "Import Materials", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("CreateComposites", "Create Composites", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("UseDiffuseSuffixOnOriginImg", "Use Diffuse Suffix for Origin Image", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("UseExistingMaterials", "Use Existing Materials", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("IgnoreMaterials", "Ignore Materials", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Animations + ImportOptionsConfigList.startGroup("Animations"); + ImportOptionsConfigList.addField("ImportAnimations", "Import Animations", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("SeparateAnimations", "Separate Animations", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("SeparateAnimationPrefix", "Separate Animation Prefix", "string", "", "", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Collision + ImportOptionsConfigList.startGroup("Collision"); + ImportOptionsConfigList.addField("GenerateCollisions", "Generate Collisions", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("GenCollisionType", "Generate Collision Type", "list", "", "CollisionMesh", "CollisionMesh,ConvexHull", %optionsObj); + ImportOptionsConfigList.addField("CollisionMeshPrefix", "CollisionMesh Prefix", "string", "", "Col", "", %optionsObj); + ImportOptionsConfigList.addField("GenerateLOSCollisions", "Generate LOS Collisions", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("GenLOSCollisionType", "Generate LOS Collision Type", "list", "", "CollisionMesh", "CollisionMesh,ConvexHull", %optionsObj); + ImportOptionsConfigList.addField("LOSCollisionMeshPrefix", "LOS CollisionMesh Prefix", "string", "", "LOS", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Images + ImportOptionsConfigList.startGroup("Image"); + ImportOptionsConfigList.addField("ImageType", "Image Type", "list", "", "N/A", "N/A,Diffuse,Normal,Specular,Metalness,Roughness,AO,Composite,GUI", %optionsObj); + ImportOptionsConfigList.addField("DiffuseTypeSuffixes", "Diffuse Type Suffixes", "command", "", "_ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL", "", %optionsObj); + ImportOptionsConfigList.addField("NormalTypeSuffixes", "Normal Type Suffixes", "command", "", "_NORMAL,_NORM", "", %optionsObj); + + if(EditorSettings.lightingModel $= "Legacy") + { + ImportOptionsConfigList.addField("SpecularTypeSuffixes", "Specular Type Suffixes", "command", "", "_SPECULAR,_SPEC", "", %optionsObj); + } + else + { + ImportOptionsConfigList.addField("MetalnessTypeSuffixes", "Metalness Type Suffixes", "command", "", "_METAL,_MET,_METALNESS,_METALLIC", "", %optionsObj); + ImportOptionsConfigList.addField("RoughnessTypeSuffixes", "Roughness Type Suffixes", "command", "", "_ROUGH,_ROUGHNESS", "", %optionsObj); + ImportOptionsConfigList.addField("SmoothnessTypeSuffixes", "Smoothness Type Suffixes", "command", "", "_SMOOTH,_SMOOTHNESS", "", %optionsObj); + ImportOptionsConfigList.addField("AOTypeSuffixes", "AO Type Suffixes", "command", "", "_AO,_AMBIENT,_AMBIENTOCCLUSION", "", %optionsObj); + ImportOptionsConfigList.addField("CompositeTypeSuffixes", "Composite Type Suffixes", "command", "", "_COMP,_COMPOSITE", "", %optionsObj); + } + + ImportOptionsConfigList.addField("TextureFilteringMode", "Texture Filtering Mode", "list", "", "Bilinear", "None,Bilinear,Trilinear", %optionsObj); + ImportOptionsConfigList.addField("UseMips", "Use Mipmaps", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("IsHDR", "Is HDR", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("Scaling", "Scaling", "float", "", "1.0", "", %optionsObj); + ImportOptionsConfigList.addField("Compressed", "Is Compressed", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("GenerateMaterialOnImport", "Generate Material On Import", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("PopulateMaterialMaps", "Populate Material Maps", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Sounds + ImportOptionsConfigList.startGroup("Sound"); + ImportOptionsConfigList.addField("VolumeAdjust", "Volume Adjustment", "float", "", "1.0", "", %optionsObj); + ImportOptionsConfigList.addField("PitchAdjust", "Pitch Adjustment", "float", "", "1.0", "", %optionsObj); + ImportOptionsConfigList.addField("Compressed", "Is Compressed", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.endGroup(); +} + +function ImportAssetConfigEditorWindow::addNewConfig(%this) +{ + ImportAssetConfigEditorWindow.setVisible(1); + ImportAssetConfigEditorWindow.selectWindow(); + + %optionsObj = new ScriptObject(){}; + + ImportAssetWindow.importConfigsList.add(%optionsObj); + + //Initial, blank configuration + %optionsObj.ImportMesh = true; + %optionsObj.DoUpAxisOverride = false; + %optionsObj.UpAxisOverride = "Z_AXIS"; + %optionsObj.DoScaleOverride = false; + %optionsObj.ScaleOverride = 1.0; + %optionsObj.IgnoreNodeScale = false; + %optionsObj.AdjustCenter = false; + %optionsObj.AdjustFloor = false; + %optionsObj.CollapseSubmeshes = false; + %optionsObj.LODType = "TrailingNumber"; + //%optionsObj.TrailingNumber = 2; + %optionsObj.ImportedNodes = ""; + %optionsObj.IgnoreNodes = ""; + %optionsObj.ImportMeshes = ""; + %optionsObj.IgnoreMeshes = ""; + + //Materials + %optionsObj.ImportMaterials = true; + %optionsObj.CreateComposites = true; + %optionsObj.UseDiffuseSuffixOnOriginImg = true; + %optionsObj.UseExistingMaterials = true; + + //Animations + %optionsObj.ImportAnimations = true; + %optionsObj.SeparateAnimations = true; + %optionsObj.SeparateAnimationPrefix = ""; + + //Collision + %optionsObj.GenerateCollisions = true; + %optionsObj.GenCollisionType = "CollisionMesh"; + %optionsObj.CollisionMeshPrefix = "Col"; + %optionsObj.GenerateLOSCollisions = true; + %optionsObj.GenLOSCollisionType = "CollisionMesh"; + %optionsObj.LOSCollisionMeshPrefix = "LOS"; + + //Images + %optionsObj.ImageType = "N/A"; + %optionsObj.DiffuseTypeSuffixes = "_ALBEDO;_DIFFUSE;_ALB;_DIF;_COLOR;_COL;_BASECOLOR;_BASE_COLOR"; + %optionsObj.NormalTypeSuffixes = "_NORMAL;_NORM"; + %optionsObj.SpecularTypeSuffixes = "_SPECULAR;_SPEC"; + %optionsObj.MetalnessTypeSuffixes = "_METAL;_MET;_METALNESS;_METALLIC"; + %optionsObj.RoughnessTypeSuffixes = "_ROUGH;_ROUGHNESS"; + %optionsObj.SmoothnessTypeSuffixes = "_SMOOTH;_SMOOTHNESS"; + %optionsObj.AOTypeSuffixes = "_AO;_AMBIENT;_AMBIENTOCCLUSION"; + %optionsObj.CompositeTypeSuffixes = "_COMP;_COMPOSITE"; + %optionsObj.TextureFilteringMode = "Bilinear"; + %optionsObj.UseMips = true; + %optionsObj.IsHDR = false; + %optionsObj.Scaling = 1.0; + %optionsObj.Compressed = true; + %optionsObj.GenerateMaterialOnImport = true; + %optionsObj.PopulateMaterialMaps = true; + + //Sounds + %optionsObj.VolumeAdjust = 1.0; + %optionsObj.PitchAdjust = 1.0; + %optionsObj.Compressed = false; + + //Hook in the UI + %this.populateConfigList(%optionsObj); +} + +function ImportAssetConfigEditorWindow::editConfig(%this) +{ + ImportAssetConfigEditorWindow.setVisible(1); + ImportAssetConfigEditorWindow.selectWindow(); + + %this.populateConfigList(ImportAssetWindow.activeImportConfig); +} + +function ImportAssetConfigEditorWindow::deleteConfig(%this) +{ + ImportAssetWindow.importConfigsList.erase(ImportAssetWindow.activeImportConfigIndex); + ImportAssetConfigList.setSelected(0); //update it + + ImportAssetConfigEditorWindow.saveAssetOptionsConfig(); +} + +function ImportAssetConfigEditorWindow::saveAssetOptionsConfig(%this) +{ + %xmlDoc = new SimXMLDocument(); + + %xmlDoc.pushNewElement("AssetImportConfigs"); + + for(%i = 0; %i < ImportAssetWindow.importConfigsList.count(); %i++) + { + %configObj = ImportAssetWindow.importConfigsList.getKey(%i); + + %xmlDoc.pushNewElement("Config"); + + if(%configObj.Name $= "") + %configObj.Name = AssetImportConfigName.getText(); + + %xmlDoc.setAttribute("Name", %configObj.Name); + + %xmlDoc.pushNewElement("Mesh"); + %xmlDoc.setAttribute("ImportMesh", %configObj.ImportMesh); + %xmlDoc.setAttribute("DoUpAxisOverride", %configObj.DoUpAxisOverride); + %xmlDoc.setAttribute("UpAxisOverride", %configObj.UpAxisOverride); + %xmlDoc.setAttribute("DoScaleOverride", %configObj.DoScaleOverride); + %xmlDoc.setAttribute("ScaleOverride", %configObj.ScaleOverride); + %xmlDoc.setAttribute("IgnoreNodeScale", %configObj.IgnoreNodeScale); + %xmlDoc.setAttribute("AdjustCenter", %configObj.AdjustCenter); + %xmlDoc.setAttribute("AdjustFloor", %configObj.AdjustFloor); + %xmlDoc.setAttribute("CollapseSubmeshes", %configObj.CollapseSubmeshes); + %xmlDoc.setAttribute("LODType", %configObj.LODType); + %xmlDoc.setAttribute("ImportedNodes", %configObj.ImportedNodes); + %xmlDoc.setAttribute("IgnoreNodes", %configObj.IgnoreNodes); + %xmlDoc.setAttribute("ImportMeshes", %configObj.ImportMeshes); + %xmlDoc.setAttribute("IgnoreMeshes", %configObj.IgnoreMeshes); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Materials"); + %xmlDoc.setAttribute("ImportMaterials", %configObj.ImportMaterials); + %xmlDoc.setAttribute("CreateComposites", %configObj.CreateComposites); + %xmlDoc.setAttribute("UseDiffuseSuffixOnOriginImg", %configObj.UseDiffuseSuffixOnOriginImg); + %xmlDoc.setAttribute("UseExistingMaterials", %configObj.UseExistingMaterials); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Animations"); + %xmlDoc.setAttribute("ImportAnimations", %configObj.ImportAnimations); + %xmlDoc.setAttribute("SeparateAnimations", %configObj.SeparateAnimations); + %xmlDoc.setAttribute("SeparateAnimationPrefix", %configObj.SeparateAnimationPrefix); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Collisions"); + %xmlDoc.setAttribute("GenerateCollisions", %configObj.GenerateCollisions); + %xmlDoc.setAttribute("GenCollisionType", %configObj.GenCollisionType); + %xmlDoc.setAttribute("CollisionMeshPrefix", %configObj.CollisionMeshPrefix); + %xmlDoc.setAttribute("GenerateLOSCollisions", %configObj.GenerateLOSCollisions); + %xmlDoc.setAttribute("GenLOSCollisionType", %configObj.GenLOSCollisionType); + %xmlDoc.setAttribute("LOSCollisionMeshPrefix", %configObj.LOSCollisionMeshPrefix); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Images"); + %xmlDoc.setAttribute("ImageType", %configObj.ImageType); + %xmlDoc.setAttribute("DiffuseTypeSuffixes", %configObj.DiffuseTypeSuffixes); + %xmlDoc.setAttribute("NormalTypeSuffixes", %configObj.NormalTypeSuffixes); + %xmlDoc.setAttribute("SpecularTypeSuffixes", %configObj.SpecularTypeSuffixes); + %xmlDoc.setAttribute("MetalnessTypeSuffixes", %configObj.MetalnessTypeSuffixes); + %xmlDoc.setAttribute("RoughnessTypeSuffixes", %configObj.RoughnessTypeSuffixes); + %xmlDoc.setAttribute("SmoothnessTypeSuffixes", %configObj.SmoothnessTypeSuffixes); + %xmlDoc.setAttribute("AOTypeSuffixes", %configObj.AOTypeSuffixes); + %xmlDoc.setAttribute("CompositeTypeSuffixes", %configObj.CompositeTypeSuffixes); + %xmlDoc.setAttribute("TextureFilteringMode", %configObj.TextureFilteringMode); + %xmlDoc.setAttribute("UseMips", %configObj.UseMips); + %xmlDoc.setAttribute("IsHDR", %configObj.IsHDR); + %xmlDoc.setAttribute("Scaling", %configObj.Scaling); + %xmlDoc.setAttribute("Compressed", %configObj.Compressed); + %xmlDoc.setAttribute("GenerateMaterialOnImport", %configObj.GenerateMaterialOnImport); + %xmlDoc.setAttribute("PopulateMaterialMaps", %configObj.PopulateMaterialMaps); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Sounds"); + %xmlDoc.setAttribute("VolumeAdjust", %configObj.VolumeAdjust); + %xmlDoc.setAttribute("PitchAdjust", %configObj.PitchAdjust); + %xmlDoc.setAttribute("Compressed", %configObj.Compressed); + %xmlDoc.popElement(); + + %xmlDoc.popElement(); + } + + %xmlDoc.popElement(); + + %xmlDoc.saveFile($AssetBrowser::importConfigsFile); + + ImportAssetConfigEditorWindow.setVisible(0); + ImportAssetWindow.reloadImportOptionConfigs(); +} + +function ImportOptionsConfigList::ToggleImportMesh(%this, %fieldName, %newValue, %ownerObject) +{ + %this.setFieldEnabled("DoUpAxisOverride", %newValue); + %this.setFieldEnabled("UpAxisOverride", %newValue); + %this.setFieldEnabled("DoScaleOverride", %newValue); + %this.setFieldEnabled("ScaleOverride", %newValue); + %this.setFieldEnabled("IgnoreNodeScale", %newValue); + %this.setFieldEnabled("AdjustCenter", %newValue); + %this.setFieldEnabled("AdjustFloor", %newValue); + %this.setFieldEnabled("CollapseSubmeshes", %newValue); + %this.setFieldEnabled("LODType", %newValue); + %this.setFieldEnabled("ImportedNodes", %newValue); + %this.setFieldEnabled("IgnoreNodes", %newValue); + %this.setFieldEnabled("ImportMeshes", %newValue); + %this.setFieldEnabled("IgnoreMeshes", %newValue); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.cs new file mode 100644 index 000000000..bc80f8977 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.cs @@ -0,0 +1,371 @@ +function AssetBrowser_editAsset::saveAsset(%this) +{ + %file = AssetDatabase.getAssetFilePath(%this.editedAssetId); + %success = TamlWrite(AssetBrowser_editAsset.editedAsset, %file); + + AssetBrowser.loadFilters(); + + Canvas.popDialog(AssetBrowser_editAsset); +} + +function AssetBrowser::editAsset(%this) +{ + //Find out what type it is + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %assetType = %assetDef.getClassName(); + + if(%assetType $= "MaterialAsset") + { + //if(EditorSettings.materialEditMode $= "MaterialEditor") + //{ + %assetDef.materialDefinitionName.reload(); + + EditorGui.setEditor(MaterialEditorPlugin); + + MaterialEditorGui.currentMaterial = %assetDef.materialDefinitionName; + MaterialEditorGui.setActiveMaterial( %assetDef.materialDefinitionName ); + + AssetBrowser.hideDialog(); + /*} + else + { + Canvas.pushDialog(ShaderEditor); + ShaderEditorGraph.loadGraph(%assetDef.shaderGraph); + $ShaderGen::targetShaderFile = filePath(%assetDef.shaderGraph) @"/"@fileBase(%assetDef.shaderGraph); + }*/ + } + else if(%assetType $= "StateMachineAsset") + { + eval("AssetBrowser.tempAsset = new " @ %assetDef.getClassName() @ "();"); + AssetBrowser.tempAsset.assignFieldsFrom(%assetDef); + + SMAssetEditInspector.inspect(AssetBrowser.tempAsset); + AssetBrowser_editAsset.editedAssetId = EditAssetPopup.assetId; + AssetBrowser_editAsset.editedAsset = AssetBrowser.tempAsset; + + //remove some of the groups we don't need: + for(%i=0; %i < SMAssetEditInspector.getCount(); %i++) + { + %caption = SMAssetEditInspector.getObject(%i).caption; + + if(%caption $= "Ungrouped" || %caption $= "Object" || %caption $= "Editing" + || %caption $= "Persistence" || %caption $= "Dynamic Fields") + { + SMAssetEditInspector.remove(SMAssetEditInspector.getObject(%i)); + %i--; + } + } + + Canvas.pushDialog(StateMachineEditor); + StateMachineEditor.loadStateMachineAsset(EditAssetPopup.assetId); + StateMachineEditor-->Window.text = "State Machine Editor ("@EditAssetPopup.assetId@")"; + } + else if(%assetType $= "ComponentAsset") + { + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %scriptFile = %assetDef.scriptFile; + + EditorOpenFileInTorsion(makeFullPath(%scriptFile), 0); + } + else if(%assetType $= "GameObjectAsset") + { + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %scriptFile = %assetDef.scriptFilePath; + + EditorOpenFileInTorsion(makeFullPath(%scriptFile), 0); + } + else if(%assetType $= "ScriptAsset") + { + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %scriptFile = %assetDef.scriptFilePath; + + EditorOpenFileInTorsion(makeFullPath(%scriptFile), 0); + } + else if(%assetType $= "ShapeAsset") + { + %this.hideDialog(); + ShapeEditorPlugin.openShapeAsset(EditAssetPopup.assetId); + } + else if(%assetType $= "ShapeAnimationAsset") + { + %this.hideDialog(); + ShapeEditorPlugin.openShapeAsset(EditAssetPopup.assetId); + } + else if(%assetType $= "LevelAsset") + { + schedule( 1, 0, "EditorOpenMission", %assetDef.LevelFile); + } + else if(%assetType $= "GUIAsset") + { + if(!isObject(%assetDef.assetName)) + { + exec(%assetDef.GUIFilePath); + exec(%assetDef.mScriptFilePath); + } + + GuiEditContent(%assetDef.assetName); + } +} + +function AssetBrowser::editAssetInfo(%this) +{ + Canvas.pushDialog(AssetBrowser_editAsset); + + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + + eval("AssetBrowser.tempAsset = new " @ %assetDef.getClassName() @ "();"); + AssetBrowser.tempAsset.assignFieldsFrom(%assetDef); + + AssetEditInspector.inspect(AssetBrowser.tempAsset); + AssetBrowser_editAsset.editedAssetId = EditAssetPopup.assetId; + AssetBrowser_editAsset.editedAsset = AssetBrowser.tempAsset; + + //remove some of the groups we don't need: + for(%i=0; %i < AssetEditInspector.getCount(); %i++) + { + %caption = AssetEditInspector.getObject(%i).caption; + + if(%caption $= "Ungrouped" || %caption $= "Object" || %caption $= "Editing" + || %caption $= "Persistence" || %caption $= "Dynamic Fields") + { + AssetEditInspector.remove(AssetEditInspector.getObject(%i)); + %i--; + } + } +} + +//------------------------------------------------------------ + +function AssetBrowser::refreshAsset(%this, %assetId) +{ + if(%assetId $= "") + { + //if we have no passed-in asset ID, we're probably going through the popup menu, so get our edit popup id + %assetId = EditAssetPopup.assetId; + } + + AssetDatabase.refreshAsset(%assetId); + AssetBrowser.refreshPreviews(); +} + +//------------------------------------------------------------ + +function AssetBrowser::renameAsset(%this) +{ + //Find out what type it is + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + + %curFirstResponder = AssetBrowser.getFirstResponder(); + + if(%curFirstResponder != 0) + %curFirstResponder.clearFirstResponder(); + + AssetBrowser.selectedAssetPreview-->AssetNameLabel.setActive(true); + AssetBrowser.selectedAssetPreview-->AssetNameLabel.setFirstResponder(); +} + +function AssetNameField::onReturn(%this) +{ + //if the name is different to the asset's original name, rename it! + %newName = %this.getText(); + if(%this.originalAssetName !$= %this.getText()) + { + %moduleName = AssetBrowser.selectedModule; + + //do a rename! + %success = AssetDatabase.renameDeclaredAsset(%moduleName @ ":" @ %this.originalAssetName, %moduleName @ ":" @ %this.getText()); + + if(%success) + { + %newAssetId = %moduleName @ ":" @ %this.getText(); + %assetPath = AssetDatabase.getAssetFilePath(%newAssetId); + + //Rename any associated files as well + %assetDef = AssetDatabase.acquireAsset(%newAssetId); + %assetType = %assetDef.getClassName(); + + //rename the file to match + %path = filePath(%assetPath); + + if(%assetType $= "ComponentAsset") + { + %oldScriptFilePath = %assetDef.scriptFile; + %scriptFilePath = filePath(%assetDef.scriptFile); + %scriptExt = fileExt(%assetDef.scriptFile); + + %newScriptFileName = %scriptFilePath @ "/" @ %newName @ %scriptExt; + %newAssetFile = %path @ "/" @ %this.getText() @ ".asset.taml"; + + %assetDef.componentName = %newName; + %assetDef.scriptFile = %newScriptFileName; + + TamlWrite(%assetDef, %newAssetFile); + fileDelete(%assetPath); + + pathCopy(%oldScriptFilePath, %newScriptFileName); + fileDelete(%oldScriptFilePath); + + //Go through our scriptfile and replace the old namespace with the new + %editedFileContents = ""; + + %file = new FileObject(); + if ( %file.openForRead( %newScriptFileName ) ) + { + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + %line = trim( %line ); + + %editedFileContents = %editedFileContents @ strreplace(%line, %this.originalAssetName, %newName) @ "\n"; + } + + %file.close(); + } + + if(%editedFileContents !$= "") + { + %file.openForWrite(%newScriptFileName); + + %file.writeline(%editedFileContents); + + %file.close(); + } + + exec(%newScriptFileName); + } + else if(%assetType $= "StateMachineAsset") + { + %oldScriptFilePath = %assetDef.stateMachineFile; + %scriptFilePath = filePath(%assetDef.stateMachineFile); + %scriptExt = fileExt(%assetDef.stateMachineFile); + + %newScriptFileName = %scriptFilePath @ "/" @ %newName @ %scriptExt; + %newAssetFile = %path @ "/" @ %this.getText() @ ".asset.taml"; + + %assetDef.stateMachineFile = %newScriptFileName; + + TamlWrite(%assetDef, %newAssetFile); + fileDelete(%assetPath); + + pathCopy(%oldScriptFilePath, %newScriptFileName); + fileDelete(%oldScriptFilePath); + } + else if(%assetType $= "GameObjectAsset") + { + %oldScriptFilePath = %assetDef.scriptFilePath; + %scriptFilePath = filePath(%assetDef.scriptFilePath); + %scriptExt = fileExt(%assetDef.scriptFilePath); + + %oldGOFilePath = %assetDef.TAMLFilePath; + + %newScriptFileName = %scriptFilePath @ "/" @ %newName @ %scriptExt; + %newAssetFile = %path @ "/" @ %this.getText() @ ".asset.taml"; + %newGOFile = %path @ "/" @ %this.getText() @ ".taml"; + + %assetDef.gameObjectName = %newName; + %assetDef.scriptFilePath = %newScriptFileName; + %assetDef.TAMLFilePath = %newGOFile; + + TamlWrite(%assetDef, %newAssetFile); + fileDelete(%assetPath); + + pathCopy(%oldScriptFilePath, %newScriptFileName); + fileDelete(%oldScriptFilePath); + + pathCopy(%oldGOFilePath, %newGOFile); + fileDelete(%oldGOFilePath); + + //Go through our scriptfile and replace the old namespace with the new + %editedFileContents = ""; + + %file = new FileObject(); + if ( %file.openForRead( %newScriptFileName ) ) + { + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + %line = trim( %line ); + + %editedFileContents = %editedFileContents @ strreplace(%line, %this.originalAssetName, %newName) @ "\n"; + } + + %file.close(); + } + + if(%editedFileContents !$= "") + { + %file.openForWrite(%newScriptFileName); + + %file.writeline(%editedFileContents); + + %file.close(); + } + + exec(%newScriptFileName); + + //Rename in the TAML file as well + %file = new FileObject(); + if ( %file.openForRead( %newGOFile ) ) + { + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + %line = trim( %line ); + + %editedFileContents = %editedFileContents @ strreplace(%line, %this.originalAssetName, %newName) @ "\n"; + } + + %file.close(); + } + + if(%editedFileContents !$= "") + { + %file.openForWrite(%newGOFile); + + %file.writeline(%editedFileContents); + + %file.close(); + } + } + } + } + + %this.clearFirstResponder(); + %this.setActive(false); +} + +//------------------------------------------------------------ + +function AssetBrowser::duplicateAsset(%this) +{ + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + + %this.setupCreateNewAsset(%assetDef.getClassName(), AssetBrowser.selectedModule); +} + +function AssetBrowser::deleteAsset(%this) +{ + //Find out what type it is + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %assetType = %assetDef.getClassName(); + + MessageBoxOKCancel("Warning!", "This will delete the selected asset and the files associated to it, do you wish to continue?", + "AssetBrowser.confirmDeleteAsset();", ""); +} + +function AssetBrowser::confirmDeleteAsset(%this) +{ + %currentSelectedItem = AssetBrowserFilterTree.getSelectedItem(); + %currentItemParent = AssetBrowserFilterTree.getParentItem(%currentSelectedItem); + + AssetDatabase.deleteAsset(EditAssetPopup.assetId, false); + + %this.loadFilters(); + + if(!AssetBrowserFilterTree.selectItem(%currentSelectedItem)) + { + //if it failed, that means we deleted the last item in that category, and we need to do the parent + AssetBrowserFilterTree.selectItem(%currentItemParent); + AssetBrowserFilterTree.expandItem(%currentItemParent); + } +} diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/editModule.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/editModule.cs new file mode 100644 index 000000000..996bec6f0 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/editModule.cs @@ -0,0 +1,127 @@ +// +function AssetBrowser::CreateNewModule(%this) +{ + Canvas.pushDialog(AssetBrowser_AddModule); + AssetBrowser_addModuleWindow.selectWindow(); + + AssetBrowser_addModuleWindow.callbackFunction = "AssetBrowser.loadFilters();"; +} + +function AssetBrowser_editModule::saveModule(%this) +{ + //Check what special actions we may need to do, such as renames + %moduleDef = ModuleDatabase.findModule(AssetBrowser.selectedModule, 1); + + %oldModuleName = %moduleDef.ModuleID; + + if(%oldModuleName !$= AssetBrowser.tempModule.ModuleID) + { + //rename the script file and script namespaces + %oldScriptFilePath = "data/" @ %oldModuleName @ "/" @ %moduleDef.scriptFile; + %newscriptFilePath = "data/" @ AssetBrowser.tempModule.ModuleID @ "/"; + %scriptExt = fileExt(%moduleDef.scriptFile); + + %newScriptFileName = %newscriptFilePath @ "/" @ AssetBrowser.tempModule.ModuleID @ %scriptExt; + %newScriptFileOldName = %newscriptFilePath @ "/" @ %oldModuleName @ %scriptExt; + + %moduleDef.ModuleId = AssetBrowser.tempModule.ModuleID; + %moduleDef.scriptFile = AssetBrowser.tempModule.ModuleID @ %scriptExt; + + ModuleDatabase.copyModule(%moduleDef, AssetBrowser.tempModule.ModuleID, "data/" @ AssetBrowser.tempModule.ModuleID); + + //Go through our scriptfile and replace the old namespace with the new + %editedFileContents = ""; + + %file = new FileObject(); + if ( %file.openForRead( %newScriptFileOldName ) ) + { + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + %line = trim( %line ); + + %editedFileContents = %editedFileContents @ strreplace(%line, %oldModuleName, AssetBrowser.tempModule.ModuleID) @ "\n"; + } + + %file.close(); + } + + if(%editedFileContents !$= "") + { + %file.openForWrite(%newScriptFileName); + + %file.writeline(%editedFileContents); + + %file.close(); + } + + %success = fileDelete(%newScriptFileOldName); + + ModuleDatabase.unloadExplicit(%oldModuleName); + + %success = fileDelete("data/" @ %oldModuleName); + + ModuleDatabase.loadExplicit(AssetBrowser.tempModule.ModuleID); + } + + //Now, update the module file itself + //%file = ModuleDatabase.getAssetFilePath(%moduleDef.ModuleID); + //%success = TamlWrite(AssetBrowser_editAsset.editedAsset, %file); + + AssetBrowser.loadFilters(); + + Canvas.popDialog(AssetBrowser_editModule); +} + +function AssetBrowser::editModuleInfo(%this) +{ + Canvas.pushDialog(AssetBrowser_editModule); + + %moduleDef = ModuleDatabase.findModule(AssetBrowser.selectedModule, 1); + + AssetBrowser.tempModule = new ModuleDefinition(); + AssetBrowser.tempModule.assignFieldsFrom(%moduleDef); + + ModuleEditInspector.inspect(AssetBrowser.tempModule); + AssetBrowser_editModule.editedModuleId = AssetBrowser.selectedModule; + AssetBrowser_editModule.editedModule = AssetBrowser.tempModule; + + //remove some of the groups we don't need: + for(%i=0; %i < ModuleEditInspector.getCount(); %i++) + { + %caption = ModuleEditInspector.getObject(%i).caption; + + if(%caption $= "BuildId" || %caption $= "type" || %caption $= "Dependencies" || %caption $= "scriptFile" + || %caption $= "AssetTagsManifest" || %caption $= "ScopeSet" || %caption $= "ModulePath" + || %caption $= "ModuleFile" || %caption $= "ModuleFilePath" || %caption $= "ModuleScriptFilePath" ) + { + ModuleEditInspector.remove(ModuleEditInspector.getObject(%i)); + %i--; + } + } +} + +function AssetBrowser::renameModule(%this) +{ + +} + +function AssetBrowser::reloadModule(%this) +{ + ModuleDatabase.unregisterModule(AssetBrowser.SelectedModule, 1); + ModuleDatabase.loadExplicit(AssetBrowser.SelectedModule); +} + +function AssetBrowser::deleteModule(%this) +{ + +} + +function AssetBrowser::RefreshModuleDependencies(%this) +{ + //Iterate through all our modules + + //then, iterate through the module's assets + + //if an asset has a module that isn't us, queue that into the dependencies list +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/fieldTypes.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/fieldTypes.cs new file mode 100644 index 000000000..fe524ce65 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/fieldTypes.cs @@ -0,0 +1,127 @@ +function GuiVariableInspector::onInspectorFieldModified(%this, %targetObj, %fieldName, %index, %oldValue, %newValue) +{ + echo("FIELD CHANGED: " @ %fieldName @ " from " @ %oldValue @ " to " @ %newValue); +} + +function GuiInspectorVariableGroup::onConstructField(%this, %fieldName, %fieldLabel, %fieldTypeName, %fieldDesc, %fieldDefaultVal, %fieldDataVals, %ownerObj) +{ + %makeCommand = %this @ ".build" @ %fieldTypeName @ "Field(\""@ %fieldName @ "\",\"" @ %fieldLabel @ "\",\"" @ %fieldDesc @ "\",\"" @ + %fieldDefaultVal @ "\",\"" @ %fieldDataVals @ "\",\"" @ %ownerObj @"\");"; + eval(%makeCommand); +} + +function GuiInspectorVariableGroup::buildListField(%this, %fieldName, %fieldLabel, %fieldDesc, %fieldDefaultVal, %fieldDataVals, %ownerObj) +{ + %extent = 200; + + %fieldCtrl = %this.createInspectorField(); + + %extent = %this.stack.getExtent(); + + %width = mRound(%extent/2); + %height = 20; + %inset = 10; + + /*%container = new GuiControl() { + canSaveDynamicFields = "0"; + Profile = "EditorContainerProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %extent.x SPC %height; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "100"; + tooltip = %tooltip; + tooltipProfile = "EditorToolTipProfile"; + }; + + %labelControl = new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorFontHLBold"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %inset SPC "0"; + Extent = %width + %inset SPC %height; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "100"; + tooltip = %tooltip; + tooltipProfile = "EditorToolTipProfile"; + text = %fieldLabel; + maxLength = "1024"; + };*/ + + %editControl = new GuiPopUpMenuCtrl() { + class = "guiInspectorListField"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %fieldCtrl.edit.position; + Extent = %fieldCtrl.edit.extent; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = %tooltip; + text = %fieldDefaultVal; + hovertime = "1000"; + ownerObject = %ownerObj; + fieldName = %fieldName; + }; + + //set the field value + if(getSubStr(%this.fieldName, 0, 1) $= "$") + { + if(%fieldName $= "") + %editControl.setText(%fieldName); + } + else + { + //regular variable + %setCommand = %editControl @ ".setText(" @ %ownerObj @ "." @ %fieldName @ ");"; + eval(%setCommand); + } + + %listCount = getTokenCount(%fieldDataVals, ","); + + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%fieldDataVals, ",", %i); + %editControl.add(%entryText); + } + + %fieldCtrl.setCaption(%fieldLabel); + %fieldCtrl.setEditControl(%editControl); + + %this.addInspectorField(%fieldCtrl); +} + +function guiInspectorListField::onSelect( %this, %id, %text ) +{ + if(getSubStr(%this.fieldName, 0, 1) $= "$") + { + //ah, a global var, just do it straight, then + %setCommand = %this.fieldName @ " = \"" @ %text @ "\";"; + } + else + { + //regular variable + %setCommand = %this.ownerObject @ "." @ %this.fieldName @ " = \"" @ %text @ "\";"; + } + eval(%setCommand); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/gameObjectCreator.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/gameObjectCreator.cs new file mode 100644 index 000000000..a2c526251 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/gameObjectCreator.cs @@ -0,0 +1,130 @@ +function GameObjectModuleList::onWake(%this) +{ + %this.refresh(); +} + +function GameObjectModuleList::refresh(%this) +{ + %this.clear(); + + //First, get our list of modules + %moduleList = ModuleDatabase.findModules(); + + %count = getWordCount(%moduleList); + for(%i=0; %i < %count; %i++) + { + %moduleName = getWord(%moduleList, %i); + %this.add(%moduleName.ModuleId, %i); + } +} + +function GameObjectCreatorPkgBtn::onClick(%this) +{ + Canvas.pushDialog(AssetBrowser_AddModule); + AssetBrowser_addModuleWindow.selectWindow(); +} + +function GameObjectCreateBtn::onClick(%this) +{ + %className = GameObjectCreatorName.getText(); + + if(%className $= "") + { + error("Attempted to make a new Game Object with no name!"); + Canvas.popDialog(GameObjectCreator); + return; + } + + //First, find out if this one already exists. If so, we're obviously merely updating it + //also, exec any components that may exist + //find all GameObjectAssets + %assetQuery = new AssetQuery(); + if(!AssetDatabase.findAssetType(%assetQuery, "GameObjectAsset")) + return; //if we didn't find ANY, just exit + + %count = %assetQuery.getCount(); + + %createNew = true; + + for(%i=0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %gameObjectAsset = AssetDatabase.acquireAsset(%assetId); + + if(%gameObjectAsset.gameObjectName $= %className) + { + %createNew = false; + break; + } + } + + %selectedEntity = GameObjectCreator.selectedEntity; + + %selectedEntity.class = %className; + Inspector.inspect(%selectedEntity); + + if(%createNew) + { + //get the selected module data + %moduleName = GameObjectModuleList.getText(); + + %selectedEntity.gameObjectAsset = %moduleName @ ":" @ %className; + + %path = "data/" @ %moduleName @ "/gameObjects/"; + + %file = new FileObject(); + + if(%file.openForWrite(%path @ "\\" @ %className @ ".cs")) + { + %file.writeline("function " @ %className @ "::onAdd(%this)\n{\n\n}\n"); + %file.writeline("function " @ %className @ "::onRemove(%this)\n{\n\n}\n"); + + //todo, pre-write any event functions of interest + + %file.close(); + } + + //set up the paths + %tamlPath = %path @ %className @ ".taml"; + %scriptPath = %path @ %className @ ".cs"; + saveGameObject(%className, %tamlPath, %scriptPath); + + %asset = new GameObjectAsset() + { + AssetName = %className; + VersionId = 1; + gameObjectName=%className; + TAMLFilePath = %tamlPath; + scriptFilePath = %scriptPath; + }; + %assetPath = %path @ %className @ ".asset.taml"; + + //now, add the script file and a ref to the taml into our SGO manifest so we can readily spawn it later. + TamlWrite(%selectedEntity, %tamlpath); + TamlWrite(%asset, %assetPath); + + GameObjectCreator.selectedEntity = ""; + + Canvas.popDialog(GameObjectCreator); + + //Load it + %moduleDef = ModuleDatabase.findModule(%moduleName,1); + AssetDatabase.addDeclaredAsset(%moduleDef, %assetPath); + } + else + { + %moduleDef = AssetDatabase.getAssetModule(%assetId); + %moduleName = %moduleDef.ModuleId; + %path = "data/" @ %moduleName @ "/gameObjects/"; + + %selectedEntity.gameObjectAsset = %moduleName @ ":" @ %className; + + %tamlPath = %path @ %className @ ".taml"; + TamlWrite(%selectedEntity, %tamlpath); + + GameObjectCreator.selectedEntity = ""; + + Canvas.popDialog(GameObjectCreator); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.cs new file mode 100644 index 000000000..ee351a192 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.cs @@ -0,0 +1,663 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +function CreateAssetButton::onClick(%this) +{ + AddNewAssetPopup.showPopup(Canvas); +} + +function AssetBrowser_newAsset::onWake(%this) +{ + NewAssetModuleList.refresh(); + //NewComponentParentClass.setText("Component"); +} + +function AssetBrowser_newAssetWindow::onClose(%this) +{ + NewAssetPropertiesInspector.clearFields(); + Canvas.popDialog(AssetBrowser_newAsset); +} + +function NewAssetTypeList::onWake(%this) +{ + %this.refresh(); +} + +function NewAssetTypeList::refresh(%this) +{ + %this.clear(); + + //TODO: make this more automated + //%this.add("GameObject", 0); + %this.add("Component", 0); + %this.add("Image", 1); + %this.add("Material", 2); + %this.add("Shape", 3); + %this.add("Sound", 4); + %this.add("State Machine", 5); +} + +function NewAssetTypeList::onSelected(%this) +{ + %assetType = %this.getText(); + + if(%assetType $= "Component") + { + NewComponentAssetSettings.hidden = false; + } +} + +function NewAssetModuleBtn::onClick(%this) +{ + Canvas.pushDialog(AssetBrowser_AddModule); + AssetBrowser_addModuleWindow.selectWindow(); +} + +function AssetBrowser::setupCreateNewAsset(%this, %assetType, %moduleName) +{ + Canvas.pushDialog(AssetBrowser_newAsset); + + AssetBrowser_newAssetWindow.text = "New" SPC %assetType SPC "Asset"; + + NewAssetPropertiesInspector.clear(); + + NewAssetModuleList.setText(%moduleName); + + //get rid of the old one if we had one. + if(isObject(%this.newAssetSettings)) + %this.newAssetSettings.delete(); + + %this.newAssetSettings = new ScriptObject(); + + %this.newAssetSettings.assetType = %assetType; + %this.newAssetSettings.moduleName = %moduleName; + + %shortAssetTypeName = strreplace(%assetType, "Asset", ""); + + NewAssetPropertiesInspector.startGroup("General"); + NewAssetPropertiesInspector.addField("assetName", "New Asset Name", "String", "Name of the new asset", "New" @ %shortAssetTypeName, "", %this.newAssetSettings); + //NewAssetPropertiesInspector.addField("AssetType", "New Asset Type", "List", "Type of the new asset", %assetType, "Component,Image,Material,Shape,Sound,State Machine", %newAssetSettings); + + NewAssetPropertiesInspector.addField("friendlyName", "Friendly Name", "String", "Human-readable name of new asset", "", "", %this.newAssetSettings); + + NewAssetPropertiesInspector.addField("description", "Description", "Command", "Description of the new asset", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + + if(%assetType $= "ComponentAsset") + { + NewAssetPropertiesInspector.startGroup("Components"); + NewAssetPropertiesInspector.addField("parentClass", "New Asset Parent Class", "String", "Name of the new asset's parent class", "Component", "", %this.newAssetSettings); + NewAssetPropertiesInspector.addField("componentGroup", "Component Group", "String", "Name of the group of components this component asset belongs to", "", "", %this.newAssetSettings); + //NewAssetPropertiesInspector.addField("componentName", "Component Name", "String", "Name of the new component", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + } + else if(%assetType $= "LevelAsset") + { + NewAssetPropertiesInspector.startGroup("Level"); + NewAssetPropertiesInspector.addField("levelPreviewImage", "LevePreviewImage", "Image", "Preview Image for the level", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + } + else if(%assetType $= "ScriptAsset") + { + NewAssetPropertiesInspector.startGroup("Script"); + NewAssetPropertiesInspector.addField("isServerScript", "Is Server Script", "bool", "Is this script used on the server?", "1", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + } + /*else if(%assetType $= "ShapeAnimationAsset") + { + NewAssetPropertiesInspector.startGroup("Animation"); + NewAssetPropertiesInspector.addField("sourceFile", "Source File", "filename", "Source file this animation will pull from", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.addField("animationName", "Animation Name", "string", "Name of the animation clip when used in a shape", "", "", %this.newAssetSettings); + + NewAssetPropertiesInspector.addField("startFrame", "Starting Frame", "int", "Source file this animation will pull from", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.addField("endFrame", "Ending Frame", "int", "Source file this animation will pull from", "", "", %this.newAssetSettings); + + NewAssetPropertiesInspector.addField("padRotation", "Pad Rotations", "bool", "Source file this animation will pull from", "0", "", %this.newAssetSettings); + NewAssetPropertiesInspector.addField("padTransforms", "Pad Transforms", "bool", "Source file this animation will pull from", "0", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + }*/ + + return; + + if(%moduleName $= "") + { + Canvas.pushDialog(AssetBrowser_selectModule); + } + else + { + AssetBrowser.SelectedModule = %moduleName; + + if(%assetType $= "MaterialAsset") + { + createNewMaterialAsset("NewMaterial", %moduleName); + } + else if(%assetType $= "StateMachineAsset") + { + createNewStateMachineAsset("NewStateMachine", %moduleName); + } + else if(%assetType $= "ScriptAsset") + { + createNewScriptAsset("NewScriptAsset", %moduleName); + } + } +} + +//We do a quick validation that mandatory fields are filled in before passing along to the asset-type specific function +function CreateNewAsset() +{ + %assetName = AssetBrowser.newAssetSettings.assetName; + + if(%assetName $= "") + { + MessageBoxOK( "Error", "Attempted to make a new asset with no name!"); + return; + } + + //get the selected module data + %moduleName = NewAssetModuleList.getText(); + + if(%moduleName $= "") + { + MessageBoxOK( "Error", "Attempted to make a new asset with no module!"); + return; + } + + AssetBrowser.newAssetSettings.moduleName = %moduleName; + + %assetType = AssetBrowser.newAssetSettings.assetType; + if(%assetType $= "") + { + MessageBoxOK( "Error", "Attempted to make a new asset with no type!"); + return; + } + + if(%assetType $= "ComponentAsset") + { + //Canvas.popDialog(AssetBrowser_newComponentAsset); + //AssetBrowser_newComponentAsset-->AssetBrowserModuleList.setText(AssetBrowser.selectedModule); + %assetFilePath = createNewComponentAsset(%assetName, %path); + } + else if(%assetType $= "MaterialAsset") + { + %assetFilePath = createNewMaterialAsset(); + } + else if(%assetType $= "StateMachineAsset") + { + %assetFilePath = createNewStateMachineAsset(); + } + else if(%assetType $= "GUIAsset") + { + %assetFilePath = createNewGUIAsset(); + } + else if(%assetType $= "LevelAsset") + { + %assetFilePath = createNewLevelAsset(); + } + else if(%assetType $= "ScriptAsset") + { + %assetFilePath = createNewScriptAsset(); + } + else if(%assetType $= "ShapeAnimationAsset") + { + %assetFilePath = createShapeAnimationAsset(); + } + + Canvas.popDialog(AssetBrowser_newAsset); + + //Load it + %moduleDef = ModuleDatabase.findModule(%moduleName,1); + AssetDatabase.addDeclaredAsset(%moduleDef, %assetFilePath); + + AssetBrowser.loadFilters(); +} + +function createNewComponentAsset() +{ + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/components/" @ %assetName @ ".asset.taml"; + %scriptPath = %modulePath @ "/components/" @ %assetName @ ".cs"; + + %asset = new ComponentAsset() + { + AssetName = %assetName; + versionId = 1; + componentName = %assetName; + componentClass = AssetBrowser.newAssetSettings.parentClass; + friendlyName = AssetBrowser.newAssetSettings.friendlyName; + componentType = AssetBrowser.newAssetSettings.componentGroup; + description = AssetBrowser.newAssetSettings.description; + scriptFile = %scriptPath; + }; + + TamlWrite(%asset, %tamlpath); + + %file = new FileObject(); + + if(%file.openForWrite(%scriptPath)) + { + //TODO: enable ability to auto-embed a header for copyright or whatnot + %file.writeline("//onAdd is called when the component is created and then added to it's owner entity.\n"); + %file.writeline("//You would also add any script-defined component fields via addComponentField().\n"); + %file.writeline("function " @ %assetName @ "::onAdd(%this)\n{\n\n}\n"); + %file.writeline("//onAdd is called when the component is removed and deleted from it's owner entity."); + %file.writeline("function " @ %assetName @ "::onRemove(%this)\n{\n\n}\n"); + %file.writeline("//onClientConnect is called any time a new client connects to the server."); + %file.writeline("function " @ %assetName @ "::onClientConnect(%this, %client)\n{\n\n}\n"); + %file.writeline("//onClientDisconnect is called any time a client disconnects from the server."); + %file.writeline("function " @ %assetName @ "::onClientDisonnect(%this, %client)\n{\n\n}\n"); + %file.writeline("//update is called when the component does an update tick.\n"); + %file.writeline("function " @ %assetName @ "::Update(%this)\n{\n\n}\n"); + + %file.close(); + } + + Canvas.popDialog(AssetBrowser_newComponentAsset); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Components"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewMaterialAsset() +{ + %assetName = AssetBrowser.newAssetSettings.assetName; + + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %tamlpath = %modulePath @ "/materials/" @ %assetName @ ".asset.taml"; + %sgfPath = %modulePath @ "/materials/" @ %assetName @ ".sgf"; + + %asset = new MaterialAsset() + { + AssetName = %assetName; + versionId = 1; + shaderData = ""; + shaderGraph = %sgfPath; + }; + + TamlWrite(%asset, %tamlpath); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Materials"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewScriptAsset() +{ + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/scripts/" @ %assetName @ ".asset.taml"; + %scriptPath = %modulePath @ "/scripts/" @ %assetName @ ".cs"; + + %asset = new ScriptAsset() + { + AssetName = %assetName; + versionId = 1; + scriptFilePath = %scriptPath; + }; + + TamlWrite(%asset, %tamlpath); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Scripts"); + + AssetBrowserFilterTree.onSelect(%smItem); + + %file = new FileObject(); + + if(%file.openForWrite(%scriptPath)) + { + %file.close(); + } + + return %tamlpath; +} + +function createNewStateMachineAsset() +{ + %assetName = AssetBrowser.newAssetSettings.assetName; + + %assetQuery = new AssetQuery(); + + %matchingAssetCount = AssetDatabase.findAssetName(%assetQuery, %assetName); + + %i=1; + while(%matchingAssetCount > 0) + { + %newAssetName = %assetName @ %i; + %i++; + + %matchingAssetCount = AssetDatabase.findAssetName(%assetQuery, %newAssetName); + } + + %assetName = %newAssetName; + + %assetQuery.delete(); + + %tamlpath = "data/" @ %moduleName @ "/stateMachines/" @ %assetName @ ".asset.taml"; + %smFilePath = "data/" @ %moduleName @ "/stateMachines/" @ %assetName @ ".xml"; + + %asset = new StateMachineAsset() + { + AssetName = %assetName; + versionId = 1; + stateMachineFile = %smFilePath; + }; + + %xmlDoc = new SimXMLDocument(); + %xmlDoc.saveFile(%smFilePath); + %xmlDoc.delete(); + + TamlWrite(%asset, %tamlpath); + + //Now write our XML file + %xmlFile = new FileObject(); + %xmlFile.openForWrite(%smFilePath); + %xmlFile.writeLine(""); + %xmlFile.writeLine(""); + %xmlFile.close(); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "StateMachines"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewGUIAsset() +{ + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/GUIs/" @ %assetName @ ".asset.taml"; + %guipath = %modulePath @ "/GUIs/" @ %assetName @ ".gui"; + %scriptPath = %modulePath @ "/GUIs/" @ %assetName @ ".cs"; + + %asset = new GUIAsset() + { + AssetName = %assetName; + versionId = 1; + scriptFilePath = %scriptPath; + guiFilePath = %guipath; + }; + + TamlWrite(%asset, %tamlpath); + + %file = new FileObject(); + + if(%file.openForWrite(%guipath)) + { + %file.writeline("//--- OBJECT WRITE BEGIN ---"); + %file.writeline("%guiContent = new GuiControl(" @ %assetName @ ") {"); + %file.writeline(" position = \"0 0\";"); + %file.writeline(" extent = \"100 100\";"); + %file.writeline("};"); + %file.writeline("//--- OBJECT WRITE END ---"); + + %file.close(); + } + + if(%file.openForWrite(%scriptPath)) + { + %file.writeline("function " @ %assetName @ "::onWake(%this)\n{\n\n}\n"); + %file.writeline("function " @ %assetName @ "::onSleep(%this)\n{\n\n}\n"); + + %file.close(); + } + + //load the gui + exec(%guipath); + exec(%scriptPath); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "GUIs"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewLevelAsset() +{ + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/levels/" @ %assetName @ ".asset.taml"; + %levelPath = %modulePath @ "/levels/" @ %assetName @ ".mis"; + + %asset = new LevelAsset() + { + AssetName = %assetName; + versionId = 1; + LevelFile = %levelPath; + LevelDescription = AssetBrowser.newAssetSettings.levelDescription; + PreviewImage = AssetBrowser.newAssetSettings.levelPreviewImage; + }; + + TamlWrite(%asset, %tamlpath); + + if(!pathCopy("tools/levels/BlankRoom.mis", %levelPath, false)) + { + echo("Unable to copy template level file!"); + } + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Levels"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewShapeAnimationAsset() +{ + %dlg = new OpenFileDialog() + { + Filters = "Animation Files(*.dae, *.cached.dts)|*.dae;*.cached.dts"; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = false; + OverwritePrompt = true; + forceRelativePath = false; + //MultipleFiles = true; + }; + + %ret = %dlg.Execute(); + + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %fullPath = %dlg.FileName; + } + + %dlg.delete(); + + if ( !%ret ) + return; + + /*%moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/levels/" @ %assetName @ ".asset.taml"; + %levelPath = %modulePath @ "/levels/" @ %assetName @ ".mis"; + + %asset = new ShapeAnimationAsset() + { + AssetName = %assetName; + versionId = 1; + LevelFile = %levelPath; + LevelDescription = AssetBrowser.newAssetSettings.levelDescription; + PreviewImage = AssetBrowser.newAssetSettings.levelPreviewImage; + }; + + TamlWrite(%asset, %tamlpath); + + if(!pathCopy("tools/levels/BlankRoom.mis", %levelPath, false)) + { + echo("Unable to copy template level file!"); + } + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Levels"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath;*/ +} + +function ParentComponentList::onWake(%this) +{ + %this.refresh(); +} + +function ParentComponentList::refresh(%this) +{ + %this.clear(); + + %assetQuery = new AssetQuery(); + if(!AssetDatabase.findAssetType(%assetQuery, "ComponentAsset")) + return; //if we didn't find ANY, just exit + + // Find all the types. + %count = %assetQuery.getCount(); + + /*%categories = ""; + for (%i = 0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %componentAsset = AssetDatabase.acquireAsset(%assetId); + %componentName = %componentAsset.componentName; + + if(%componentName $= "") + %componentName = %componentAsset.componentClass; + + %this.add(%componentName, %i); + }*/ + + %categories = ""; + for (%i = 0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %componentAsset = AssetDatabase.acquireAsset(%assetId); + %componentClass = %componentAsset.componentClass; + if (!isInList(%componentClass, %categories)) + %categories = %categories TAB %componentClass; + } + + %categories = trim(%categories); + + %index = 0; + %categoryCount = getFieldCount(%categories); + for (%i = 0; %i < %categoryCount; %i++) + { + %category = getField(%categories, %i); + %this.addCategory(%category); + + for (%j = 0; %j < %count; %j++) + { + %assetId = %assetQuery.getAsset(%j); + + %componentAsset = AssetDatabase.acquireAsset(%assetId); + %componentName = %componentAsset.componentName; + %componentClass = %componentAsset.componentClass; + + if (%componentClass $= %category) + { + if(%componentName !$= "") + %this.add(" "@%componentName, %i); + } + } + } +} + +//---------------------------------------------------------- +// Game Object creation +//---------------------------------------------------------- +function EWorldEditor::createGameObject( %this ) +{ + GameObjectCreatorObjectName.text = ""; + + %activeSelection = %this.getActiveSelection(); + if( %activeSelection.getCount() == 0 ) + return; + + GameObjectCreator.selectedEntity = %activeSelection.getObject( 0 ); + + Canvas.pushDialog(GameObjectCreator); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.cs new file mode 100644 index 000000000..12f422485 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.cs @@ -0,0 +1,154 @@ +function AssetBrowser::buildPopupMenus(%this) +{ + if( !isObject( AddNewModulePopup ) ) + { + new PopupMenu( AddNewModulePopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + isPopup = true; + + item[ 0 ] = "Create New Module" TAB "" TAB "AssetBrowser.CreateNewModule();"; + item[ 1 ] = "Refresh Module Dependencies" TAB "" TAB "AssetBrowser.RefreshModuleDependencies();"; + }; + } + + if( !isObject( EditAssetPopup ) ) + { + new PopupMenu( EditAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + item[ 0 ] = "Edit Asset" TAB "" TAB "AssetBrowser.editAsset();"; + item[ 1 ] = "Rename Asset" TAB "" TAB "AssetBrowser.renameAsset();"; + item[ 2 ] = "Refresh Asset" TAB "" TAB "AssetBrowser.refreshAsset();"; + item[ 3 ] = "Asset Properties" TAB "" TAB "AssetBrowser.editAssetInfo();"; + item[ 4 ] = "-"; + Item[ 5 ] = "Duplicate Asset" TAB "" TAB "AssetBrowser.duplicateAsset();"; + item[ 6 ] = "-"; + item[ 7 ] = "Re-Import Asset" TAB "" TAB "AssetBrowser.reImportAsset();"; + item[ 8 ] = "-"; + item[ 9 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; + + jumpFileName = ""; + jumpLineNumber = ""; + }; + } + + if( !isObject( AddNewComponentAssetPopup ) ) + { + new PopupMenu( AddNewComponentAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + //item[ 0 ] = "Create Component" TAB "" TAB "Canvas.pushDialog(AssetBrowser_newComponentAsset); AssetBrowser_newComponentAsset-->NewComponentPackageList.setText(AssetBrowser.selectedModule);"; + item[ 0 ] = "Component" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ComponentAsset\", AssetBrowser.selectedModule);"; + + //list other common component types here to shortcut the creation process + }; + } + + if( !isObject( AddNewScriptAssetPopup ) ) + { + %this.AddNewScriptAssetPopup = new PopupMenu( AddNewScriptAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + item[ 0 ] = "Create Component" TAB AddNewComponentAssetPopup; + item[ 1 ] = "Create Script" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ScriptAsset\", AssetBrowser.selectedModule);"; + item[ 2 ] = "Create State Machine" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"StateMachineAsset\", AssetBrowser.selectedModule);"; + //item[ 3 ] = "-"; + //item[ 3 ] = "Create Game Object" TAB "" TAB "AssetBrowser.createNewGameObjectAsset(\"NewGameObject\", AssetBrowser.selectedModule);"; + }; + //%this.AddNewScriptAssetPopup.insertSubMenu(0, "Create Component", AddNewComponentAssetPopup); + } + + if( !isObject( AddNewArtAssetPopup ) ) + { + %this.AddNewArtAssetPopup = new PopupMenu( AddNewArtAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + item[ 0 ] = "Create Material" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"MaterialAsset\", AssetBrowser.selectedModule);";//"createNewMaterialAsset(\"NewMaterial\", AssetBrowser.selectedModule);"; + item[ 1 ] = "Create Image" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ImageAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewImageAsset(\"NewImage\", AssetBrowser.selectedModule);"; + item[ 2 ] = "-"; + item[ 3 ] = "Create Shape" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"Shape\", AssetBrowser.selectedModule);"; + item[ 4 ] = "Create Shape Animation" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ShapeAnimationAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewShapeAnimationAsset(\"NewShapeAnimation\", AssetBrowser.selectedModule);"; + item[ 5 ] = "-"; + item[ 6 ] = "Create GUI" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"GUIAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewGUIAsset(\"NewGUI\", AssetBrowser.selectedModule);"; + item[ 7 ] = "-"; + item[ 8 ] = "Create Post Effect" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"PostEffectAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewPostEffectAsset(\"NewPostEffect\", AssetBrowser.selectedModule);"; + item[ 9 ] = "-"; + item[ 10 ] = "Create Sound" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"SoundAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewSoundAsset(\"NewSound\", AssetBrowser.selectedModule);"; + item[ 11 ] = "-"; + item[ 12 ] = "Create Particle Effect" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ParticleEffectAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewParticleEffectAsset(\"NewParticleEffect\", AssetBrowser.selectedModule);"; + }; + } + + if( !isObject( AddNewAssetPopup ) ) + { + %this.AddNewAssetPopup = new PopupMenu( AddNewAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + + item[0] = "Create Code Asset" TAB AddNewScriptAssetPopup; + item[1] = "-"; + item[2] = "Create Art Asset" TAB AddNewArtAssetPopup; + item[3] = "-"; + item[4] = "Create Level" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"LevelAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewLevelAsset(\"NewLevel\", AssetBrowser.selectedModule);"; + }; + } + + if( !isObject( EditModulePopup ) ) + { + new PopupMenu( EditModulePopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + item[ 0 ] = "Create New Asset" TAB AddNewAssetPopup; + item[ 1 ] = "Reload Module" TAB "" TAB "AssetBrowser.reloadModule();"; + Item[ 2 ] = "-"; + Item[ 3 ] = "Edit Module" TAB "" TAB "AssetBrowser.editModuleInfo();"; + Item[ 4 ] = "-"; + Item[ 5 ] = "Duplicate Module" TAB "" TAB "AssetBrowser.copyModule();"; + Item[ 6 ] = "-"; + Item[ 7 ] = "Delete Module" TAB "" TAB "AssetBrowser.deleteModule();"; + }; + } + + //Some assets are not yet ready/implemented, so disable their creation here + AddNewArtAssetPopup.enableItem(3, false); //shape + AddNewArtAssetPopup.enableItem(4, false); //shape animation + AddNewArtAssetPopup.enableItem(8, false); //post effect + AddNewArtAssetPopup.enableItem(10, false); //sound asset + AddNewArtAssetPopup.enableItem(12, false); //particle effect + + AddNewScriptAssetPopup.enableItem(2, false); //state machine +} + +function AddNewScriptAssetPopupMenu::onSelectItem(%this, %id, %text) +{ + return true; +} +function AddNewScriptAssetPopupMenu::setupDefaultState(%this) +{ + // Setup camera speed gui's. Both menu and editorgui + %this.setupGuiControls(); + + Parent::setupDefaultState(%this); +} + +function AddNewScriptAssetPopupMenu::setupGuiControls(%this) +{ +} diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/selectModule.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/selectModule.cs new file mode 100644 index 000000000..3c2c7c1ea --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/selectModule.cs @@ -0,0 +1,17 @@ +function AssetBrowser_selectModule::onWake(%this) +{ + AssetBrowser_SelectModuleWindow-->ModuleList.refresh(); +} + +function SelectModule_NewAssetModuleBtn::onClick(%this) +{ + Canvas.pushDialog(AssetBrowser_AddModule); + AssetBrowser_addModuleWindow.selectWindow(); + + AssetBrowser_AddModule.callback = "AssetBrowser_selectModule.newModuleAdded();"; +} + +function AssetBrowser_selectModule::newModuleAdded(%this) +{ + AssetBrowser_SelectModuleWindow-->ModuleList.refresh(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/selectPackage.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/selectPackage.cs new file mode 100644 index 000000000..42f66ddb1 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/selectPackage.cs @@ -0,0 +1,17 @@ +function AssetBrowser_selectPackage::onWake(%this) +{ + AssetBrowser_SelectPackageWindow-->packageList.refresh(); +} + +function SelectPackage_NewAssetPackageBtn::onClick(%this) +{ + Canvas.pushDialog(AssetBrowser_AddPackage); + AssetBrowser_addPackageWindow.selectWindow(); + + AssetBrowser_AddPackage.callback = "AssetBrowser_selectPackage.newPackageAdded();"; +} + +function AssetBrowser_selectPackage::newPackageAdded(%this) +{ + AssetBrowser_SelectPackageWindow-->packageList.refresh(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/base/images/materials.cs b/Templates/BaseGame/game/tools/base/images/materials.cs index 11b766b04..a407c2ed2 100644 --- a/Templates/BaseGame/game/tools/base/images/materials.cs +++ b/Templates/BaseGame/game/tools/base/images/materials.cs @@ -16,7 +16,6 @@ singleton CubemapData( BlankSkyCubemap ) singleton Material( BlankSkyMat ) { cubemap = BlankSkyCubemap; - isSky = true; }; singleton Material(White) diff --git a/Templates/BaseGame/game/tools/base/images/sky_skybox.dml b/Templates/BaseGame/game/tools/base/images/sky_skybox.dml deleted file mode 100644 index 5ca0a1cb6..000000000 --- a/Templates/BaseGame/game/tools/base/images/sky_skybox.dml +++ /dev/null @@ -1,7 +0,0 @@ -skybox_1 -skybox_2 -skybox_3 -skybox_4 -skybox_5 -skybox_6 -skybox_6 \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs b/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs index 696b98975..f2de82d96 100644 --- a/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs +++ b/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs @@ -35,5 +35,4 @@ exec("./GuiEaseEditDlg.ed.cs"); exec("./guiObjectInspector.ed.cs"); exec("./uvEditor.ed.gui"); exec("./objectSelection.ed.cs"); -exec("./guiPlatformGenericMenubar.ed.cs"); exec("./postFxManager.gui"); \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs b/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs deleted file mode 100644 index 089b0b8fa..000000000 --- a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs +++ /dev/null @@ -1,19 +0,0 @@ -if(isClass(GuiPlatformGenericMenuBar)) -{ - exec("./guiPlatformGenericMenubar.ed.gui"); -} -else -{ - %guiContent = new GuiControl(PlatformGenericMenubar) { - profile = "GuiModelessDialogProfile"; - - new GuiControl() - { - internalName = "menubar"; - extent = "1024 20"; - minExtent = "320 20"; - horizSizing = "width"; - profile = "GuiMenuBarProfile"; - }; - }; -} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui b/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui deleted file mode 100644 index 8d2cbcd74..000000000 --- a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui +++ /dev/null @@ -1,14 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -%guiContent = new GuiControl(PlatformGenericMenubar) { - profile = "GuiModelessDialogProfile"; - - new GuiPlatformGenericMenuBar() - { - internalName = "menubar"; - extent = "1024 20"; - minExtent = "320 20"; - horizSizing = "width"; - profile = "GuiMenuBarProfile"; - }; -}; -//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/images/iconError.png b/Templates/BaseGame/game/tools/gui/images/iconError.png new file mode 100644 index 000000000..b0947dd84 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconError.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconWarn.png b/Templates/BaseGame/game/tools/gui/images/iconWarn.png new file mode 100644 index 000000000..4c97ba74b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconWarn.png differ diff --git a/Templates/BaseGame/game/tools/gui/profiles.ed.cs b/Templates/BaseGame/game/tools/gui/profiles.ed.cs index 04e8df5b2..a1b120e0d 100644 --- a/Templates/BaseGame/game/tools/gui/profiles.ed.cs +++ b/Templates/BaseGame/game/tools/gui/profiles.ed.cs @@ -287,6 +287,31 @@ new GuiControlProfile( ToolsGuiTextEditProfile ) category = "Tools"; }; +if( !isObject( ToolsGuiTextEditCenterProfile ) ) +new GuiControlProfile (ToolsGuiTextEditCenterProfile) +{ + opaque = true; + //bitmap = "./images/textEditFrame"; + //hasBitmapArray = true; + border = -2; // fix to display textEdit img + //borderWidth = "1"; // fix to display textEdit img + //borderColor = "100 100 100"; + fillColor = "255 255 255 0"; + fillColorHL = "72 72 72"; + fillColorSEL = "255 255 255"; + fontColor = "196 196 196 255"; + fontColorHL = "255 255 255"; + fontColorSEL = "0 0 0"; + fontColorNA = "196 196 196 255"; + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = true; + justify = "center"; + tab = true; + canKeyFocus = true; + category = "Tools"; +}; + if( !isObject( ToolsGuiNumericTextEditProfile ) ) new GuiControlProfile( ToolsGuiNumericTextEditProfile : ToolsGuiTextEditProfile ) { @@ -1068,10 +1093,14 @@ singleton GuiControlProfile( GuiMenuBarProfile ) { fillcolor = "255 255 255"; fillcolorHL = "213 231 248"; - borderColor = "98 163 229"; - borderColorHL = "122 177 232"; - border = 0; + + fontColorNA = "180 180 180"; + + border = 1; borderThickness = 1; + borderColor = "128 128 128"; + borderColorHL = "122 177 232"; + opaque = true; mouseOverSelected = true; category = "Editor"; diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.cs index 61dc8c5e7..e68c2e3db 100644 --- a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.cs +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.cs @@ -223,7 +223,7 @@ function GuiEditor::switchToWorldEditor( %this ) function GuiEditor::enableMenuItems(%this, %val) { - %menu = GuiEditCanvas.menuBar->EditMenu.getID(); + %menu = GuiEditCanvas.menuBar.findMenu("Edit").getID(); %menu.enableItem( 3, %val ); // cut %menu.enableItem( 4, %val ); // copy @@ -239,8 +239,8 @@ function GuiEditor::enableMenuItems(%this, %val) %menu.enableItem( 18, %val ); // group %menu.enableItem( 19, %val ); // ungroup - GuiEditCanvas.menuBar->LayoutMenu.enableAllItems( %val ); - GuiEditCanvas.menuBar->MoveMenu.enableAllItems( %val ); + GuiEditCanvas.menuBar.findMenu("Layout").enableAllItems( %val ); + GuiEditCanvas.menuBar.findMenu("Move").enableAllItems( %val ); } //--------------------------------------------------------------------------------------------- @@ -294,7 +294,7 @@ function GuiEditor::updateUndoMenu(%this) %nextUndo = %uman.getNextUndoName(); %nextRedo = %uman.getNextRedoName(); - %editMenu = GuiEditCanvas.menuBar->editMenu; + %editMenu = GuiEditCanvas.menuBar.findMenu("Edit"); %editMenu.setItemName( 0, "Undo " @ %nextUndo ); %editMenu.setItemName( 1, "Redo " @ %nextRedo ); @@ -443,7 +443,7 @@ function GuiEditor::setPreviewResolution( %this, %width, %height ) function GuiEditor::toggleEdgeSnap( %this ) { %this.snapToEdges = !%this.snapToEdges; - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_EDGESNAP_INDEX, %this.snapToEdges ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_EDGESNAP_INDEX, %this.snapToEdges ); GuiEditorEdgeSnapping_btn.setStateOn( %this.snapToEdges ); } @@ -452,7 +452,7 @@ function GuiEditor::toggleEdgeSnap( %this ) function GuiEditor::toggleCenterSnap( %this ) { %this.snapToCenters = !%this.snapToCenters; - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CENTERSNAP_INDEX, %this.snapToCenters ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_CENTERSNAP_INDEX, %this.snapToCenters ); GuiEditorCenterSnapping_btn.setStateOn( %this.snapToCenters ); } @@ -461,7 +461,7 @@ function GuiEditor::toggleCenterSnap( %this ) function GuiEditor::toggleFullBoxSelection( %this ) { %this.fullBoxSelection = !%this.fullBoxSelection; - GuiEditCanvas.menuBar->EditMenu.checkItem( $GUI_EDITOR_MENU_FULLBOXSELECT_INDEX, %this.fullBoxSelection ); + GuiEditCanvas.menuBar.findMenu("Edit").checkItem( $GUI_EDITOR_MENU_FULLBOXSELECT_INDEX, %this.fullBoxSelection ); } //--------------------------------------------------------------------------------------------- @@ -469,7 +469,7 @@ function GuiEditor::toggleFullBoxSelection( %this ) function GuiEditor::toggleDrawGuides( %this ) { %this.drawGuides= !%this.drawGuides; - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_DRAWGUIDES_INDEX, %this.drawGuides ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_DRAWGUIDES_INDEX, %this.drawGuides ); } //--------------------------------------------------------------------------------------------- @@ -477,7 +477,7 @@ function GuiEditor::toggleDrawGuides( %this ) function GuiEditor::toggleGuideSnap( %this ) { %this.snapToGuides = !%this.snapToGuides; - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GUIDESNAP_INDEX, %this.snapToGuides ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_GUIDESNAP_INDEX, %this.snapToGuides ); } //--------------------------------------------------------------------------------------------- @@ -485,7 +485,7 @@ function GuiEditor::toggleGuideSnap( %this ) function GuiEditor::toggleControlSnap( %this ) { %this.snapToControls = !%this.snapToControls; - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CONTROLSNAP_INDEX, %this.snapToControls ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_CONTROLSNAP_INDEX, %this.snapToControls ); } //--------------------------------------------------------------------------------------------- @@ -493,7 +493,7 @@ function GuiEditor::toggleControlSnap( %this ) function GuiEditor::toggleCanvasSnap( %this ) { %this.snapToCanvas = !%this.snapToCanvas; - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CANVASSNAP_INDEX, %this.snapToCanvas ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_CANVASSNAP_INDEX, %this.snapToCanvas ); } //--------------------------------------------------------------------------------------------- @@ -506,7 +506,7 @@ function GuiEditor::toggleGridSnap( %this ) else %this.setSnapToGrid( %this.snap2GridSize ); - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GRIDSNAP_INDEX, %this.snap2Grid ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_GRIDSNAP_INDEX, %this.snap2Grid ); GuiEditorSnapCheckBox.setStateOn( %this.snap2Grid ); } @@ -993,14 +993,14 @@ function GuiEditorGui::onWake( %this ) // Set up initial menu toggle states. - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_EDGESNAP_INDEX, GuiEditor.snapToEdges ); - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CENTERSNAP_INDEX, GuiEditor.snapToCenters ); - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GUIDESNAP_INDEX, GuiEditor.snapToGuides ); - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CONTROLSNAP_INDEX, GuiEditor.snapToControls ); - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CANVASSNAP_INDEX, GuiEditor.snapToCanvas ); - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GRIDSNAP_INDEX, GuiEditor.snap2Grid ); - GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_DRAWGUIDES_INDEX, GuiEditor.drawGuides ); - GuiEditCanvas.menuBar->EditMenu.checkItem( $GUI_EDITOR_MENU_FULLBOXSELECT_INDEX, GuiEditor.fullBoxSelection ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_EDGESNAP_INDEX, GuiEditor.snapToEdges ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_CENTERSNAP_INDEX, GuiEditor.snapToCenters ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_GUIDESNAP_INDEX, GuiEditor.snapToGuides ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_CONTROLSNAP_INDEX, GuiEditor.snapToControls ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_CANVASSNAP_INDEX, GuiEditor.snapToCanvas ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_GRIDSNAP_INDEX, GuiEditor.snap2Grid ); + GuiEditCanvas.menuBar.findMenu("Snap").checkItem( $GUI_EDITOR_MENU_DRAWGUIDES_INDEX, GuiEditor.drawGuides ); + GuiEditCanvas.menuBar.findMenu("Edit").checkItem( $GUI_EDITOR_MENU_FULLBOXSELECT_INDEX, GuiEditor.fullBoxSelection ); // Sync toolbar buttons. diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs index 1305ae170..83317d0d8 100644 --- a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs @@ -66,9 +66,13 @@ function GuiEditCanvas::onCreateMenu(%this) } // Menu bar - %this.menuBar = new MenuBar() + %this.menuBar = new GuiMenuBar(GuiEditorMenubar) { dynamicItemInsertPos = 3; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; new PopupMenu() { diff --git a/Templates/BaseGame/game/tools/levels/BlankRoom.mis b/Templates/BaseGame/game/tools/levels/BlankRoom.mis index d8cd0768b..3d43918be 100644 --- a/Templates/BaseGame/game/tools/levels/BlankRoom.mis +++ b/Templates/BaseGame/game/tools/levels/BlankRoom.mis @@ -24,9 +24,9 @@ new SimGroup(MissionGroup) { soundDistanceModel = "Linear"; canSave = "1"; canSaveDynamicFields = "1"; - desc0 = "A blank room ready to be populated with Torque objects. Guns, anyone?"; + desc0 = "A blank room template that acts as a starting point."; enabled = "1"; - levelName = "Blank Room"; + levelName = "Blank Room Template"; }; new SkyBox(theSky) { Material = "BlankSkyMat"; diff --git a/Templates/BaseGame/game/tools/main.cs b/Templates/BaseGame/game/tools/main.cs index dd238eac0..0941c29a4 100644 --- a/Templates/BaseGame/game/tools/main.cs +++ b/Templates/BaseGame/game/tools/main.cs @@ -122,6 +122,17 @@ package Tools if( isFunction( %initializeFunction ) ) call( %initializeFunction ); } + + //Now, go through and load any tool-group modules + ModuleDatabase.setModuleExtension("module"); + + //Any common tool modules + ModuleDatabase.scanModules( "tools", false ); + ModuleDatabase.LoadGroup( "Tool" ); + + //Do any tools that come in with a gameplay package. These are usually specialized tools + //ModuleDatabase.scanModules( "data", false ); + //ModuleDatabase.LoadGroup( "Tool" ); // Popuplate the default SimObject icons that // are used by the various editors. @@ -214,6 +225,29 @@ package Tools } }; +function EditorCreateFakeGameSession(%fileName) +{ + // Create a local game server and connect to it. + if(isObject(ServerGroup)) + ServerGroup.delete(); + + new SimGroup(ServerGroup); + + if(isObject(ServerConnection)) + ServerConnection.delete(); + + new GameConnection(ServerConnection); + + // This calls GameConnection::onConnect. + ServerConnection.connectLocal(); + + $instantGroup = ServerGroup; + + $Game::MissionGroup = "MissionGroup"; + + exec(%file); +} + function fastLoadWorldEdit(%val) { if(%val) @@ -222,37 +256,64 @@ function fastLoadWorldEdit(%val) { onStart(); } - - if(!$Game::running) + + %timerId = startPrecisionTimer(); + + if( GuiEditorIsActive() ) + toggleGuiEditor(1); + + if( !$missionRunning ) { - //startGame(); - activatePackage( "BootEditor" ); - ChooseLevelDlg.launchInEditor = false; - StartGame("tools/levels/BlankRoom.mis", "SinglePlayer"); - - if(!isObject(Observer)) - { - datablock CameraData(Observer) {}; - } - - %cam = new Camera() - { - datablock = Observer; - }; - - %cam.scopeToClient(LocalClientConnection); - - LocalClientConnection.setCameraObject(%cam); - LocalClientConnection.setControlObject(%cam); - - LocalClientConnection.camera = %cam; - - %cam.setPosition("0 0 0"); + // Flag saying, when level is chosen, launch it with the editor open. + ChooseLevelDlg.launchInEditor = true; + Canvas.pushDialog( ChooseLevelDlg ); } else - { - toggleEditor(true); + { + pushInstantGroup(); + + if ( !isObject( Editor ) ) + { + Editor::create(); + MissionCleanup.add( Editor ); + MissionCleanup.add( Editor.getUndoManager() ); + } + + if( EditorIsActive() ) + { + if (theLevelInfo.type $= "DemoScene") + { + commandToServer('dropPlayerAtCamera'); + Editor.close("SceneGui"); + } + else + { + Editor.close("PlayGui"); + } + } + else + { + canvas.pushDialog( EditorLoadingGui ); + canvas.repaint(); + + Editor.open(); + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. + cancel($Game::Schedule); + + if (theLevelInfo.type $= "DemoScene") + commandToServer('dropCameraAtPlayer', true); + + canvas.popDialog(EditorLoadingGui); + } + + popInstantGroup(); } + + %elapsed = stopPrecisionTimer( %timerId ); + warn( "Time spent in toggleEditor() : " @ %elapsed / 1000.0 @ " s" ); } } diff --git a/Templates/BaseGame/game/tools/shapeEditor/main.cs b/Templates/BaseGame/game/tools/shapeEditor/main.cs index 721313e95..efbc1c538 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/main.cs +++ b/Templates/BaseGame/game/tools/shapeEditor/main.cs @@ -145,6 +145,13 @@ function ShapeEditorPlugin::onWorldEditorStartup(%this) } } +function ShapeEditorPlugin::openShapeAsset(%this, %assetId) +{ + %this.selectedAssetId = %assetId; + %this.selectedAssetDef = AssetDatabase.acquireAsset(%assetId); + %this.open(%this.selectedAssetDef.fileName); +} + function ShapeEditorPlugin::open(%this, %filename) { if ( !%this.isActivated ) diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.cs b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.cs index d79923776..9675ac7c9 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.cs +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.cs @@ -611,6 +611,19 @@ function ShapeEdPropWindow::update_onShapeSelectionChanged( %this ) ShapeEdSequenceList.addItem( %name ); } ShapeEdThreadWindow.onAddThread(); // add thread 0 + + //Now, fetch any animation assets if we're utilizing a shape asset + if(ShapeEditorPlugin.selectedAssetId !$= "") + { + %animationAssetCount = ShapeEditorPlugin.selectedAssetDef.getAnimationCount(); + + for(%animIdx = 0; %animIdx < %animationAssetCount; %animIdx++) + { + %animAsset = ShapeEditorPlugin.selectedAssetDef.getAnimation(%animIdx); + + //ShapeEdSequenceList.addItem( %animAsset.assetName ); + } + } // --- DETAILS TAB --- // Add detail levels and meshes to tree @@ -789,7 +802,8 @@ function ShapeEdSeqNodeTabBook::onTabSelected( %this, %name, %index ) { case "Seq": ShapeEdPropWindow-->newBtn.ToolTip = "Add new sequence"; - ShapeEdPropWindow-->newBtn.Command = "ShapeEdSequences.onAddSequence();"; + //ShapeEdPropWindow-->newBtn.Command = "ShapeEdSequences.onAddSequence();"; + ShapeEdPropWindow-->newBtn.Command = "AssetBrowser.showDialog(\"ShapeAnimationAsset\", \"onAddAnimationAssetShapeEditor\", \"\", \"\", \"\");"; ShapeEdPropWindow-->newBtn.setActive( true ); ShapeEdPropWindow-->deleteBtn.ToolTip = "Delete selected sequence (cannot be undone)"; ShapeEdPropWindow-->deleteBtn.Command = "ShapeEdSequences.onDeleteSequence();"; diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs index 2c48b25a1..15bd4cc9b 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs @@ -299,6 +299,12 @@ function ActionEditNodeTransform::undo( %this ) //------------------------------------------------------------------------------ // Add sequence +function onAddAnimationAssetShapeEditor(%selectedAnimation) +{ + echo("SELECTED MUH ASSET"); + ShapeEditor.doAddSequence(%selectedAnimation, 0, 0, 0); +} + function ShapeEditor::doAddSequence( %this, %seqName, %from, %start, %end ) { %action = %this.createAction( ActionAddSequence, "Add sequence" ); @@ -313,23 +319,48 @@ function ShapeEditor::doAddSequence( %this, %seqName, %from, %start, %end ) function ActionAddSequence::doit( %this ) { - // If adding this sequence from an existing sequence, make a backup copy of - // the existing sequence first, so we can edit the start/end frames later - // without having to worry if the original source sequence has changed. - if ( ShapeEditor.shape.getSequenceIndex( %this.from ) >= 0 ) + if(ShapeEditorPlugin.selectedAssetId $= "") { - %this.from = ShapeEditor.getUniqueName( "sequence", "__backup__" @ %this.origFrom @ "_" ); - ShapeEditor.shape.addSequence( %this.origFrom, %this.from ); + // If adding this sequence from an existing sequence, make a backup copy of + // the existing sequence first, so we can edit the start/end frames later + // without having to worry if the original source sequence has changed. + if ( ShapeEditor.shape.getSequenceIndex( %this.from ) >= 0 ) + { + %this.from = ShapeEditor.getUniqueName( "sequence", "__backup__" @ %this.origFrom @ "_" ); + ShapeEditor.shape.addSequence( %this.origFrom, %this.from ); + } + + // Add the sequence + $collada::forceLoadDAE = EditorSettings.value( "forceLoadDAE" ); + %success = ShapeEditor.shape.addSequence( %this.from, %this.seqName, %this.start, %this.end ); + $collada::forceLoadDAE = false; + + if ( %success ) + { + ShapeEdPropWindow.update_onSequenceAdded( %this.seqName, -1 ); + return true; + } } - - // Add the sequence - $collada::forceLoadDAE = EditorSettings.value( "forceLoadDAE" ); - %success = ShapeEditor.shape.addSequence( %this.from, %this.seqName, %this.start, %this.end ); - $collada::forceLoadDAE = false; - - if ( %success ) + else { - ShapeEdPropWindow.update_onSequenceAdded( %this.seqName, -1 ); + %assetDef = AssetDatabase.acquireAsset(%this.seqName); + %moduleName = getWord(getToken(%this.seqName, ":", 0),0); + + //TODO, properly ignore and ambient entries for our idx values, but only if they're there! + %idx = ShapeEdSequenceList.rowCount() - 2; + + %animSet = "ShapeEditorPlugin.selectedAssetDef.animationSequence"@%idx@"=\"@Asset="@%moduleName@":"@%assetDef.assetName@"\";"; + eval(%animSet); + + %assetPath = AssetDatabase.getAssetFilePath(ShapeEditorPlugin.selectedAssetId); + + %assetImportSuccessful = TAMLWrite(ShapeEditorPlugin.selectedAssetDef, %assetPath); + + AssetDatabase.refreshAsset(ShapeEditorPlugin.selectedAssetId); + + //force a refresh + ShapeEdPropWindow.update_onShapeSelectionChanged(); + return true; } return false; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs index f6e88eece..2d9e2ec53 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -1570,6 +1570,27 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) %haveObjectEntries = false; %haveLockAndHideEntries = true; + //Set up the generic pop-up pre-emptively if we haven't already + if( !isObject( ETContextPopup ) ) + { + %popup = new PopupMenu( ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; + item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; + item[ 3 ] = "-"; + item[ 4 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); EWorldEditor.syncGui();"; + item[ 5 ] = "Hidden" TAB "" TAB "EWorldEditor.hideObject( %this.object, !%this.object.hidden ); EWorldEditor.syncGui();"; + item[ 6 ] = "-"; + item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + + object = -1; + }; + } + // Handle multi-selection. if( %this.getSelectedItemsCount() > 1 ) { @@ -1616,12 +1637,67 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) item[ 0 ] = "Add Camera Bookmark" TAB "" TAB "EditorGui.addCameraBookmarkByGui();"; }; } + + else if(%obj.isMemberOfClass("Entity")) + { + %popup = EntityObjectPopup; + if(!isObject(EntityObjectPopup)) + { + %popup = new PopupMenu( EntityObjectPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; + item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; + item[ 3 ] = "-"; + item[ 4 ] = "Toggle Lock Children" TAB "" TAB "EWorldEditor.toggleLockChildren( %this.object );"; + item[ 5 ] = "Toggle Hide Children" TAB "" TAB "EWorldEditor.toggleHideChildren( %this.object );"; + item[ 6 ] = "-"; + item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + item[ 8 ] = "-"; + item[ 9 ] = "Add New Objects Here" TAB "" TAB "EWCreatorWindow.setNewObjectGroup( %this.object );"; + item[ 10 ] = "Add Children to Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, false );"; + item[ 11 ] = "Remove Children from Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, true );"; + item[ 12 ] = "-"; + item[ 13 ] = "Convert to Game Object" TAB "" TAB "EWorldEditor.createGameObject( %this.object );"; + item[ 14 ] = "Duplicate Game Object" TAB "" TAB "EWorldEditor.duplicateGameObject( %this.object );"; + item[ 15 ] = "Show in Asset Browser" TAB "" TAB "EWorldEditor.showGameObjectInAssetBrowser( %this.object );"; + + object = -1; + }; + } + + if(!isObject(AssetDatabase.acquireAsset(%obj.gameObjectAsset))) + { + EntityObjectPopup.enableItem(13, true); + EntityObjectPopup.enableItem(14, false); + EntityObjectPopup.enableItem(15, false); + } + else + { + EntityObjectPopup.enableItem(13, false); + EntityObjectPopup.enableItem(14, true); + EntityObjectPopup.enableItem(15, true); + } + + %popup.object = %obj; + + %hasChildren = %obj.getCount() > 0; + %popup.enableItem( 10, %hasChildren ); + %popup.enableItem( 11, %hasChildren ); + + %haveObjectEntries = true; + %haveLockAndHideEntries = false; + } // Open context menu if this is a SimGroup else if( !%obj.isMemberOfClass( "SceneObject" ) ) { %popup = ETSimGroupContextPopup; if( !isObject( %popup ) ) + { %popup = new PopupMenu( ETSimGroupContextPopup ) { superClass = "MenuBuilder"; @@ -1642,30 +1718,6 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) object = -1; }; - - if(%obj.isMemberOfClass("Entity")) - { - if( !isObject( GameObjectPopup ) ) - %popup = new PopupMenu( GameObjectPopup : ETSimGroupContextPopup ) - { - //item[ 12 ] = "-"; - item[ 12 ] = "Convert to Game Object" TAB "" TAB "EWorldEditor.createGameObject( %this.object );"; - item[ 13 ] = "Duplicate Game Object" TAB "" TAB "EWorldEditor.duplicateGameObject( %this.object );"; - item[ 14 ] = "Show in Asset Browser" TAB "" TAB "EWorldEditor.showGameObjectInAssetBrowser( %this.object );"; - }; - - if(!isObject(AssetDatabase.acquireAsset(%obj.gameObjectAsset))) - { - GameObjectPopup.enableItem(12, true); - GameObjectPopup.enableItem(13, false); - GameObjectPopup.enableItem(14, false); - } - else - { - GameObjectPopup.enableItem(12, false); - GameObjectPopup.enableItem(13, true); - GameObjectPopup.enableItem(14, true); - } } %popup.object = %obj; @@ -1678,77 +1730,56 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) %haveLockAndHideEntries = false; } - // Open generic context menu. - else + // Specialized version for ConvexShapes. + else if( %obj.isMemberOfClass( "ConvexShape" ) ) { - %popup = ETContextPopup; + %popup = ETConvexShapeContextPopup; if( !isObject( %popup ) ) - %popup = new PopupMenu( ETContextPopup ) + { + %popup = new PopupMenu( ETConvexShapeContextPopup : ETContextPopup ) { superClass = "MenuBuilder"; isPopup = "1"; - item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; - item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; - item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; - item[ 3 ] = "-"; - item[ 4 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); EWorldEditor.syncGui();"; - item[ 5 ] = "Hidden" TAB "" TAB "EWorldEditor.hideObject( %this.object, !%this.object.hidden ); EWorldEditor.syncGui();"; - item[ 6 ] = "-"; - item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; - - object = -1; + item[ 8 ] = "-"; + item[ 9 ] = "Convert to Zone" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Zone\" );"; + item[ 10 ] = "Convert to Portal" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Portal\" );"; + item[ 11 ] = "Convert to Occluder" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"OcclusionVolume\" );"; + item[ 12 ] = "Convert to Sound Space" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"SFXSpace\" );"; }; - - if(%obj.isMemberOfClass("Entity")) - { - %popup = ETEntityContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETEntityContextPopup : ETSimGroupContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 12 ] = "-"; - item[ 13 ] = "Convert to Game Object" TAB "" TAB "EWorldEditor.createGameObject( %this.object );"; - }; - } - - // Specialized version for ConvexShapes. - else if( %obj.isMemberOfClass( "ConvexShape" ) ) - { - %popup = ETConvexShapeContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETConvexShapeContextPopup : ETContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 8 ] = "-"; - item[ 9 ] = "Convert to Zone" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Zone\" );"; - item[ 10 ] = "Convert to Portal" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Portal\" );"; - item[ 11 ] = "Convert to Occluder" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"OcclusionVolume\" );"; - item[ 12 ] = "Convert to Sound Space" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"SFXSpace\" );"; - }; } - // Specialized version for polyhedral objects. - else if( %obj.isMemberOfClass( "Zone" ) || - %obj.isMemberOfClass( "Portal" ) || - %obj.isMemberOfClass( "OcclusionVolume" ) || - %obj.isMemberOfClass( "SFXSpace" ) ) + %popup.object = %obj; + %haveObjectEntries = true; + } + + // Specialized version for polyhedral objects. + else if( %obj.isMemberOfClass( "Zone" ) || + %obj.isMemberOfClass( "Portal" ) || + %obj.isMemberOfClass( "OcclusionVolume" ) || + %obj.isMemberOfClass( "SFXSpace" ) ) + { + %popup = ETPolyObjectContextPopup; + if( !isObject( %popup ) ) { - %popup = ETPolyObjectContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETPolyObjectContextPopup : ETContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; + %popup = new PopupMenu( ETPolyObjectContextPopup : ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; - item[ 8 ] = "-"; - item[ 9 ] = "Convert to ConvexShape" TAB "" TAB "EWorldEditor.convertSelectionToConvexShape();"; - }; + item[ 8 ] = "-"; + item[ 9 ] = "Convert to ConvexShape" TAB "" TAB "EWorldEditor.convertSelectionToConvexShape();"; + }; } + + %popup.object = %obj; + %haveObjectEntries = true; + } + + // Open generic context menu. + else + { + %popup = ETContextPopup; %popup.object = %obj; %haveObjectEntries = true; @@ -2043,7 +2074,7 @@ function EWorldEditor::syncGui( %this ) %this.syncToolPalette(); EditorTree.update(); - Editor.getUndoManager().updateUndoMenu( EditorGui.menuBar-->EditMenu ); + Editor.getUndoManager().updateUndoMenu( EditorGui.findMenu("Edit") ); EditorGuiStatusBar.setSelectionObjectsByCount( %this.getSelectionSize() ); EWTreeWindow-->LockSelection.setStateOn( %this.getSelectionLockCount() > 0 ); @@ -2279,155 +2310,6 @@ function EWorldEditor::deleteMissionObject( %this, %object ) EditorTree.buildVisibleTree( true ); } -function EWorldEditor::createGameObject( %this, %entity ) -{ - if(!isObject(GameObjectBuilder)) - { - new GuiControl(GameObjectBuilder, EditorGuiGroup) { - profile = "ToolsGuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "800 600"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - - new GuiWindowCtrl(GameObjectBuilderTargetWindow) { - profile = "ToolsGuiWindowProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "384 205"; - extent = "256 102"; - minExtent = "256 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - resizeWidth = "1"; - resizeHeight = "1"; - canMove = "1"; - canClose = "0"; - canMinimize = "0"; - canMaximize = "0"; - minSize = "50 50"; - text = "Create Object"; - - new GuiTextCtrl() { - profile = "GuiCenterTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "9 26"; - extent = "84 16"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - text = "Object Name:"; - }; - new GuiTextEditCtrl(GameObjectBuilderObjectName) { - class = ObjectBuilderGuiTextEditCtrl; - profile = "ToolsGuiTextEditProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "78 26"; - extent = "172 18"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - historySize = "0"; - }; - new GuiButtonCtrl(GameObjectBuilderOKButton) { - profile = "ToolsGuiButtonProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "7 250"; - extent = "156 24"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - command = "EWorldEditor.buildGameObject();"; - helpTag = "0"; - text = "Create New"; - Accelerator = "return"; - }; - new GuiButtonCtrl(GameObjectBuilderCancelButton) { - profile = "ToolsGuiButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "170 250"; - extent = "80 24"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - command = "Canvas.popDialog(GameObjectBuilder);"; - helpTag = "0"; - text = "Cancel"; - Accelerator = "escape"; - }; - }; - }; - - GameObjectBuilderTargetWindow.extent = getWord(GameObjectBuilderTargetWindow.extent, 0) SPC 88; - GameObjectBuilderOKButton.position = getWord(GameObjectBuilderOKButton.position, 0) SPC 57; - GameObjectBuilderCancelButton.position = getWord(GameObjectBuilderCancelButton.position, 0) SPC 57; - } - - GameObjectBuilderObjectName.text = ""; - GameObjectBuilder.selectedEntity = %entity; - - Canvas.pushDialog(GameObjectBuilder); -} - -function EWorldEditor::buildGameObject(%this) -{ - if(GameObjectBuilderObjectName.getText() $= "") - { - error("Attempted to make a new Game Object with no name!"); - Canvas.popDialog(GameObjectBuilder); - return; - } - - %path = EditorSettings.value( "WorldEditor/newGameObjectDir" ); - %className = GameObjectBuilderObjectName.getText(); - GameObjectBuilder.selectedEntity.class = %className; - Inspector.inspect(GameObjectBuilder.selectedEntity); - - %file = new FileObject(); - - if(%file.openForWrite(%path @ "\\" @ %className @ ".cs")) - { - %file.writeline("function " @ %className @ "::onAdd(%this)\n{\n\n}\n"); - %file.writeline("function " @ %className @ "::onRemove(%this)\n{\n\n}\n"); - - //todo, pre-write any event functions of interest - - %file.close(); - } - - //set up the paths - %tamlPath = %path @ "/" @ %className @ ".taml"; - %scriptPath = %path @ "/" @ %className @ ".cs"; - saveGameObject(%className, %tamlPath, %scriptPath); - - //reload it - execGameObjects(); - - //now, add the script file and a ref to the taml into our SGO manifest so we can readily spawn it later. - TamlWrite(GameObjectBuilder.selectedEntity, %tamlpath); - - GameObjectBuilder.selectedEntity = ""; - - Canvas.popDialog(GameObjectBuilder); -} - function EWorldEditor::selectAllObjectsInSet( %this, %set, %deselect ) { if( !isObject( %set ) ) diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs index f476ccaeb..8c558bfef 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs @@ -587,6 +587,13 @@ function makeSelectedAMesh() EditorTree.buildVisibleTree( true ); } +function EditorTakeControlOfEntity() +{ + %object = EWorldEditor.getSelectedObject(0); + switchCamera(localClientConnection, %object); + switchControlObject(localClientConnection, %object); +} + function EditorMount() { echo( "EditorMount" ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs index dbe978cab..e0d53a76d 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs @@ -110,9 +110,13 @@ function EditorGui::buildMenus(%this) }; // Menu bar - %this.menuBar = new MenuBar(WorldEditorMenubar) + %this.menuBar = new GuiMenuBar(WorldEditorMenubar) { dynamicItemInsertPos = 3; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; }; // File Menu @@ -158,7 +162,7 @@ function EditorGui::buildMenus(%this) %fileMenu.appendItem("Exit Level" TAB "" TAB "EditorExitMission();"); %fileMenu.appendItem("Quit" TAB %quitShortcut TAB "EditorQuitGame();"); - %this.menuBar.insert(%fileMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%fileMenu); // Edit Menu %editMenu = new PopupMenu() @@ -187,7 +191,7 @@ function EditorGui::buildMenus(%this) item[15] = "Game Options..." TAB "" TAB "Canvas.pushDialog(optionsDlg);"; item[16] = "PostEffect Manager" TAB "" TAB "Canvas.pushDialog(PostFXManager);"; }; - %this.menuBar.insert(%editMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%editMenu); // View Menu %viewMenu = new PopupMenu() @@ -201,7 +205,7 @@ function EditorGui::buildMenus(%this) item[ 0 ] = "Visibility Layers" TAB "Alt V" TAB "VisibilityDropdownToggle();"; item[ 1 ] = "Show Grid in Ortho Views" TAB %cmdCtrl @ "-Shift-Alt G" TAB "EditorGui.toggleOrthoGrid();"; }; - %this.menuBar.insert(%viewMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%viewMenu); // Camera Menu %cameraMenu = new PopupMenu() @@ -229,7 +233,7 @@ function EditorGui::buildMenus(%this) Item[15] = "Manage Bookmarks..." TAB "Ctrl-Shift B" TAB "EditorGui.toggleCameraBookmarkWindow();"; item[16] = "Jump to Bookmark" TAB %this.cameraBookmarksMenu; }; - %this.menuBar.insert(%cameraMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%cameraMenu); // Editors Menu %editorsMenu = new PopupMenu() @@ -246,7 +250,7 @@ function EditorGui::buildMenus(%this) //item[4] = "Terrain Painter" TAB "F4" TAB TerrainPainterPlugin; //item[5] = "-"; }; - %this.menuBar.insert(%editorsMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%editorsMenu); // Lighting Menu %lightingMenu = new PopupMenu() @@ -263,7 +267,7 @@ function EditorGui::buildMenus(%this) // NOTE: The light managers will be inserted as the // last menu items in EditorLightingMenu::onAdd(). }; - %this.menuBar.insert(%lightingMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%lightingMenu); // Tools Menu %toolsMenu = new PopupMenu() @@ -278,7 +282,7 @@ function EditorGui::buildMenus(%this) item[2] = "Torque SimView" TAB "" TAB "tree();"; item[3] = "Make Selected a Mesh" TAB "" TAB "makeSelectedAMesh();"; }; - %this.menuBar.insert(%toolsMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%toolsMenu); // Help Menu %helpMenu = new PopupMenu() @@ -293,7 +297,7 @@ function EditorGui::buildMenus(%this) item[2] = "Offline Reference Guide..." TAB "" TAB "shellexecute(EWorldEditor.documentationReference);"; item[3] = "Torque 3D Forums..." TAB "" TAB "gotoWebPage(EWorldEditor.forumURL);"; }; - %this.menuBar.insert(%helpMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%helpMenu); // Menus that are added/removed dynamically (temporary) @@ -375,8 +379,10 @@ function EditorGui::buildMenus(%this) Item[17] = "Make Selection Prefab" TAB "" TAB "EditorMakePrefab();"; Item[18] = "Explode Selected Prefab" TAB "" TAB "EditorExplodePrefab();"; Item[19] = "-"; - Item[20] = "Mount Selection A to B" TAB "" TAB "EditorMount();"; - Item[21] = "Unmount Selected Object" TAB "" TAB "EditorUnmount();"; + Item[20] = "Take control of entity" TAB "" TAB "EditorTakeControlOfEntity();"; + Item[21] = "-"; + Item[22] = "Mount Selection A to B" TAB "" TAB "EditorMount();"; + Item[23] = "Unmount Selected Object" TAB "" TAB "EditorUnmount();"; }; } } @@ -398,9 +404,9 @@ function EditorGui::setMenuDefaultState(%this) if(! isObject(%this.menuBar)) return 0; - for(%i = 0;%i < %this.menuBar.getCount();%i++) + for(%i = 0;%i < %this.menuBar.getMenuCount();%i++) { - %menu = %this.menuBar.getObject(%i); + %menu = %this.menuBar.getMenu(%i); %menu.setupDefaultState(); } @@ -414,9 +420,10 @@ function EditorGui::findMenu(%this, %name) if(! isObject(%this.menuBar)) return 0; - for(%i = 0;%i < %this.menuBar.getCount();%i++) + + for(%i = 0; %i < %this.menuBar.getMenuCount(); %i++) { - %menu = %this.menuBar.getObject(%i); + %menu = %this.menuBar.getMenu(%i); if(%name $= %menu.barTitle) return %menu; diff --git a/Templates/Full/game/art/skies/Desert_Sky/materials.cs b/Templates/Full/game/art/skies/Desert_Sky/materials.cs index 0ee4080d8..af6a979c8 100644 --- a/Templates/Full/game/art/skies/Desert_Sky/materials.cs +++ b/Templates/Full/game/art/skies/Desert_Sky/materials.cs @@ -34,5 +34,4 @@ singleton Material( DesertSkyMat ) { cubemap = DesertSkyCubemap; materialTag0 = "Skies"; - isSky = true; }; diff --git a/Templates/Full/game/art/skies/night/materials.cs b/Templates/Full/game/art/skies/night/materials.cs index 11f9f6348..79cc050fc 100644 --- a/Templates/Full/game/art/skies/night/materials.cs +++ b/Templates/Full/game/art/skies/night/materials.cs @@ -34,7 +34,6 @@ singleton Material( NightSkyMat ) { cubemap = NightCubemap; materialTag0 = "Skies"; - isSky = true; }; singleton Material( Moon_Glow_Mat ) @@ -51,5 +50,4 @@ singleton Material( Moon_Mat ) emissive = true; translucent = true; vertColor[ 0 ] = true; - isSky = true; }; diff --git a/Templates/Full/game/core/art/skies/blank/materials.cs b/Templates/Full/game/core/art/skies/blank/materials.cs index 39f268866..53709d11d 100644 --- a/Templates/Full/game/core/art/skies/blank/materials.cs +++ b/Templates/Full/game/core/art/skies/blank/materials.cs @@ -34,7 +34,6 @@ singleton Material( BlackSkyMat ) { cubemap = BlackSkyCubemap; materialTag0 = "Skies"; - isSky = true; }; singleton CubemapData( BlueSkyCubemap ) diff --git a/Templates/Full/game/tools/gui/guiDialogs.ed.cs b/Templates/Full/game/tools/gui/guiDialogs.ed.cs index db09e8570..dc6b4e3a3 100644 --- a/Templates/Full/game/tools/gui/guiDialogs.ed.cs +++ b/Templates/Full/game/tools/gui/guiDialogs.ed.cs @@ -35,4 +35,3 @@ exec("./GuiEaseEditDlg.ed.cs"); exec("./guiObjectInspector.ed.cs"); exec("./uvEditor.ed.gui"); exec("./objectSelection.ed.cs"); -exec("./guiPlatformGenericMenubar.ed.cs"); diff --git a/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.cs b/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.cs deleted file mode 100644 index 089b0b8fa..000000000 --- a/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.cs +++ /dev/null @@ -1,19 +0,0 @@ -if(isClass(GuiPlatformGenericMenuBar)) -{ - exec("./guiPlatformGenericMenubar.ed.gui"); -} -else -{ - %guiContent = new GuiControl(PlatformGenericMenubar) { - profile = "GuiModelessDialogProfile"; - - new GuiControl() - { - internalName = "menubar"; - extent = "1024 20"; - minExtent = "320 20"; - horizSizing = "width"; - profile = "GuiMenuBarProfile"; - }; - }; -} \ No newline at end of file diff --git a/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.gui b/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.gui deleted file mode 100644 index 8d2cbcd74..000000000 --- a/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.gui +++ /dev/null @@ -1,14 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -%guiContent = new GuiControl(PlatformGenericMenubar) { - profile = "GuiModelessDialogProfile"; - - new GuiPlatformGenericMenuBar() - { - internalName = "menubar"; - extent = "1024 20"; - minExtent = "320 20"; - horizSizing = "width"; - profile = "GuiMenuBarProfile"; - }; -}; -//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/Full/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs b/Templates/Full/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs index 1305ae170..83317d0d8 100644 --- a/Templates/Full/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs +++ b/Templates/Full/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs @@ -66,9 +66,13 @@ function GuiEditCanvas::onCreateMenu(%this) } // Menu bar - %this.menuBar = new MenuBar() + %this.menuBar = new GuiMenuBar(GuiEditorMenubar) { dynamicItemInsertPos = 3; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; new PopupMenu() { diff --git a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs index bc1905292..535d00880 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -2017,7 +2017,7 @@ function EWorldEditor::syncGui( %this ) %this.syncToolPalette(); EditorTree.update(); - Editor.getUndoManager().updateUndoMenu( EditorGui.menuBar-->EditMenu ); + Editor.getUndoManager().updateUndoMenu( EditorGui.findMenu("Edit") ); EditorGuiStatusBar.setSelectionObjectsByCount( %this.getSelectionSize() ); EWTreeWindow-->LockSelection.setStateOn( %this.getSelectionLockCount() > 0 ); diff --git a/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs index dbe978cab..b225d3534 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs @@ -110,9 +110,13 @@ function EditorGui::buildMenus(%this) }; // Menu bar - %this.menuBar = new MenuBar(WorldEditorMenubar) + %this.menuBar = new GuiMenuBar(WorldEditorMenubar) { dynamicItemInsertPos = 3; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; }; // File Menu @@ -158,7 +162,7 @@ function EditorGui::buildMenus(%this) %fileMenu.appendItem("Exit Level" TAB "" TAB "EditorExitMission();"); %fileMenu.appendItem("Quit" TAB %quitShortcut TAB "EditorQuitGame();"); - %this.menuBar.insert(%fileMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%fileMenu); // Edit Menu %editMenu = new PopupMenu() @@ -187,7 +191,7 @@ function EditorGui::buildMenus(%this) item[15] = "Game Options..." TAB "" TAB "Canvas.pushDialog(optionsDlg);"; item[16] = "PostEffect Manager" TAB "" TAB "Canvas.pushDialog(PostFXManager);"; }; - %this.menuBar.insert(%editMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%editMenu); // View Menu %viewMenu = new PopupMenu() @@ -201,7 +205,7 @@ function EditorGui::buildMenus(%this) item[ 0 ] = "Visibility Layers" TAB "Alt V" TAB "VisibilityDropdownToggle();"; item[ 1 ] = "Show Grid in Ortho Views" TAB %cmdCtrl @ "-Shift-Alt G" TAB "EditorGui.toggleOrthoGrid();"; }; - %this.menuBar.insert(%viewMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%viewMenu); // Camera Menu %cameraMenu = new PopupMenu() @@ -229,7 +233,7 @@ function EditorGui::buildMenus(%this) Item[15] = "Manage Bookmarks..." TAB "Ctrl-Shift B" TAB "EditorGui.toggleCameraBookmarkWindow();"; item[16] = "Jump to Bookmark" TAB %this.cameraBookmarksMenu; }; - %this.menuBar.insert(%cameraMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%cameraMenu); // Editors Menu %editorsMenu = new PopupMenu() @@ -246,7 +250,7 @@ function EditorGui::buildMenus(%this) //item[4] = "Terrain Painter" TAB "F4" TAB TerrainPainterPlugin; //item[5] = "-"; }; - %this.menuBar.insert(%editorsMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%editorsMenu); // Lighting Menu %lightingMenu = new PopupMenu() @@ -263,7 +267,7 @@ function EditorGui::buildMenus(%this) // NOTE: The light managers will be inserted as the // last menu items in EditorLightingMenu::onAdd(). }; - %this.menuBar.insert(%lightingMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%lightingMenu); // Tools Menu %toolsMenu = new PopupMenu() @@ -278,7 +282,7 @@ function EditorGui::buildMenus(%this) item[2] = "Torque SimView" TAB "" TAB "tree();"; item[3] = "Make Selected a Mesh" TAB "" TAB "makeSelectedAMesh();"; }; - %this.menuBar.insert(%toolsMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%toolsMenu); // Help Menu %helpMenu = new PopupMenu() @@ -293,7 +297,7 @@ function EditorGui::buildMenus(%this) item[2] = "Offline Reference Guide..." TAB "" TAB "shellexecute(EWorldEditor.documentationReference);"; item[3] = "Torque 3D Forums..." TAB "" TAB "gotoWebPage(EWorldEditor.forumURL);"; }; - %this.menuBar.insert(%helpMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%helpMenu); // Menus that are added/removed dynamically (temporary) @@ -398,9 +402,9 @@ function EditorGui::setMenuDefaultState(%this) if(! isObject(%this.menuBar)) return 0; - for(%i = 0;%i < %this.menuBar.getCount();%i++) + for(%i = 0;%i < %this.menuBar.getMenuCount();%i++) { - %menu = %this.menuBar.getObject(%i); + %menu = %this.menuBar.getMenu(%i); %menu.setupDefaultState(); } @@ -414,9 +418,10 @@ function EditorGui::findMenu(%this, %name) if(! isObject(%this.menuBar)) return 0; - for(%i = 0;%i < %this.menuBar.getCount();%i++) + + for(%i = 0; %i < %this.menuBar.getMenuCount(); %i++) { - %menu = %this.menuBar.getObject(%i); + %menu = %this.menuBar.getMenu(%i); if(%name $= %menu.barTitle) return %menu; diff --git a/Templates/Modules/FPSGameplay/FPSGameplay.module b/Templates/Modules/FPSGameplay/FPSGameplay.module index 9833352e2..37623bf1e 100644 --- a/Templates/Modules/FPSGameplay/FPSGameplay.module +++ b/Templates/Modules/FPSGameplay/FPSGameplay.module @@ -7,4 +7,9 @@ DestroyFunction="destroy" Group="Game" Dependencies="clientServer=1,UI=1"> + \ No newline at end of file diff --git a/Templates/Modules/FPSGameplay/art/environment/precipitation/rain.dml b/Templates/Modules/FPSGameplay/art/environment/precipitation/rain.dml deleted file mode 100644 index 3893393dd..000000000 --- a/Templates/Modules/FPSGameplay/art/environment/precipitation/rain.dml +++ /dev/null @@ -1 +0,0 @@ -rain diff --git a/Templates/Modules/FPSGameplay/art/skies/Blank_sky/materials.cs b/Templates/Modules/FPSGameplay/art/skies/Blank_sky/materials.cs index 4f0ddc658..493573f5b 100644 --- a/Templates/Modules/FPSGameplay/art/skies/Blank_sky/materials.cs +++ b/Templates/Modules/FPSGameplay/art/skies/Blank_sky/materials.cs @@ -16,5 +16,4 @@ singleton CubemapData( BlankSkyCubemap ) singleton Material( BlankSkyMat ) { cubemap = BlankSkyCubemap; - isSky = true; }; diff --git a/Templates/Modules/FPSGameplay/art/skies/Blank_sky/sky_skybox.dml b/Templates/Modules/FPSGameplay/art/skies/Blank_sky/sky_skybox.dml deleted file mode 100644 index 5ca0a1cb6..000000000 --- a/Templates/Modules/FPSGameplay/art/skies/Blank_sky/sky_skybox.dml +++ /dev/null @@ -1,7 +0,0 @@ -skybox_1 -skybox_2 -skybox_3 -skybox_4 -skybox_5 -skybox_6 -skybox_6 \ No newline at end of file diff --git a/Templates/Modules/FPSGameplay/art/skies/Desert_Sky/materials.cs b/Templates/Modules/FPSGameplay/art/skies/Desert_Sky/materials.cs index 0ee4080d8..af6a979c8 100644 --- a/Templates/Modules/FPSGameplay/art/skies/Desert_Sky/materials.cs +++ b/Templates/Modules/FPSGameplay/art/skies/Desert_Sky/materials.cs @@ -34,5 +34,4 @@ singleton Material( DesertSkyMat ) { cubemap = DesertSkyCubemap; materialTag0 = "Skies"; - isSky = true; }; diff --git a/Templates/Modules/FPSGameplay/art/skies/night/materials.cs b/Templates/Modules/FPSGameplay/art/skies/night/materials.cs index 252c8c52e..79cc050fc 100644 --- a/Templates/Modules/FPSGameplay/art/skies/night/materials.cs +++ b/Templates/Modules/FPSGameplay/art/skies/night/materials.cs @@ -34,7 +34,6 @@ singleton Material( NightSkyMat ) { cubemap = NightCubemap; materialTag0 = "Skies"; - isSky = true; }; singleton Material( Moon_Glow_Mat ) diff --git a/Templates/Modules/FPSGameplay/levels/EmptyLevel.asset.taml b/Templates/Modules/FPSGameplay/levels/EmptyLevel.asset.taml new file mode 100644 index 000000000..4f33dbd9f --- /dev/null +++ b/Templates/Modules/FPSGameplay/levels/EmptyLevel.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/Modules/FPSGameplay/levels/EmptyTerrain.asset.taml b/Templates/Modules/FPSGameplay/levels/EmptyTerrain.asset.taml new file mode 100644 index 000000000..657070e50 --- /dev/null +++ b/Templates/Modules/FPSGameplay/levels/EmptyTerrain.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/Modules/FPSGameplay/levels/Outpost.asset.taml b/Templates/Modules/FPSGameplay/levels/Outpost.asset.taml new file mode 100644 index 000000000..3f70498f0 --- /dev/null +++ b/Templates/Modules/FPSGameplay/levels/Outpost.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/Modules/spectatorGameplay/SpectatorGameplay.module b/Templates/Modules/spectatorGameplay/SpectatorGameplay.module index 953932b87..08e040082 100644 --- a/Templates/Modules/spectatorGameplay/SpectatorGameplay.module +++ b/Templates/Modules/spectatorGameplay/SpectatorGameplay.module @@ -7,4 +7,9 @@ DestroyFunction="destroy" Group="Game" Dependencies="clientServer=1,UI=1"> + \ No newline at end of file diff --git a/Templates/Modules/spectatorGameplay/art/skies/Blank_sky/sky_skybox.dml b/Templates/Modules/spectatorGameplay/art/skies/Blank_sky/sky_skybox.dml deleted file mode 100644 index 5ca0a1cb6..000000000 --- a/Templates/Modules/spectatorGameplay/art/skies/Blank_sky/sky_skybox.dml +++ /dev/null @@ -1,7 +0,0 @@ -skybox_1 -skybox_2 -skybox_3 -skybox_4 -skybox_5 -skybox_6 -skybox_6 \ No newline at end of file diff --git a/Templates/Modules/spectatorGameplay/levels/Empty_Room.asset.taml b/Templates/Modules/spectatorGameplay/levels/Empty_Room.asset.taml new file mode 100644 index 000000000..c3917fcd3 --- /dev/null +++ b/Templates/Modules/spectatorGameplay/levels/Empty_Room.asset.taml @@ -0,0 +1,7 @@ + diff --git a/Tools/CMake/torque3d.cmake b/Tools/CMake/torque3d.cmake index ccd0c0882..f5813ccba 100644 --- a/Tools/CMake/torque3d.cmake +++ b/Tools/CMake/torque3d.cmake @@ -325,18 +325,13 @@ addPath("${srcDir}/T3D/decal") addPath("${srcDir}/T3D/sfx") addPath("${srcDir}/T3D/gameBase") addPath("${srcDir}/T3D/turret") -addPath("${srcDir}/T3D/components/") -addPath("${srcDir}/T3D/components/animation") -addPath("${srcDir}/T3D/components/camera") -addPath("${srcDir}/T3D/components/collision") -addPath("${srcDir}/T3D/components/game") -addPath("${srcDir}/T3D/components/physics") -addPath("${srcDir}/T3D/components/render") +addPathRec("${srcDir}/T3D/components/") +addPathRec("${srcDir}/T3D/systems") addPath("${srcDir}/main/") addPath("${srcDir}/assets") addPath("${srcDir}/module") -addPath("${srcDir}/T3D/assets") +addPathRec("${srcDir}/T3D/assets") addPathRec("${srcDir}/persistence") addPathRec("${srcDir}/ts/collada") addPathRec("${srcDir}/ts/loader") @@ -643,13 +638,6 @@ if(WIN32) if(TORQUE_OPENGL) addLib(OpenGL32.lib) endif() - - # JTH: DXSDK is compiled with older runtime, and MSVC 2015+ is when __vsnprintf is undefined. - # This is a workaround by linking with the older legacy library functions. - # See this for more info: http://stackoverflow.com/a/34230122 - if (MSVC14) - addLib(legacy_stdio_definitions.lib) - endif() endif() if (APPLE)